App server e client che invieranno file e altre informazioni tra loro

0

Sto provando a fare un server e programmi client, che comunicano tra loro, ma non riesco a capire il modo migliore per farlo, quindi lasciami spiegare cosa mi serve:

  • L'app Server dovrebbe essere in grado di accettare sia i file che altre informazioni (come gli array di stringhe, se possibile) dall'app client.
  • L'app client deve essere in grado di ricevere comandi dall'app Server (come SEND_REPORT, STOP_SELF ....)
  • L'intera comunicazione server-client deve essere diretta

Ho provato a utilizzare un server FTP per questo, ma per farlo è necessario un programma di terze parti (a meno che non crei da solo la mia app Server un server FTP). Così ora sto provando a farlo con TcpClient e NetworkStream, ma ho capito che non ci sarebbe stato modo di distinguere se le informazioni inviate sono un file o una semplice serie di stringhe.

Ecco quello che ho finora, il codice lato server:

private void handleClient(TcpClient client) {
        NetworkStream stream = client.GetStream();
        stream.WriteByte(1);
        FileStream fileStream = File.Open(le_path, FileMode.Create);
        int read;
        int totalRead = 0;
        byte[] buffer = new byte[1024];
        while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) {
            fileStream.Write(buffer, 0, read);
            totalRead += read;
        }
        fileStream.Dispose();
        client.Close();
    }

Questo codice crea un file, ma è bug, o non lo so, non lascia mai il ciclo while e non va mai a Dispose and Close ... Posso accedere al file quando chiudo il programma.

Ecco il codice dell'app client:

client = new TcpClient();
client.Connect(serverIP, serverPort);
byte[] file = File.ReadAllBytes(Constants.TARGET_PATH_LOGS + "squad.jpg");
byte[] fileBuffer = new byte[file.Length];
NetworkStream stream = client.GetStream();
stream.Write(file, 0, fileBuffer.GetLength(0));

Quindi ecco cosa ti sto chiedendo:

  • Se questo è il modo migliore per farlo, come posso fare in modo che il codice di ricezione riconosca se si tratta di un file inviato, o di un semplice elenco di dati di array, e come posso renderlo in grado di accettare qualsiasi file (che significa ottenere correttamente il nome, i metadati ...)
  • In caso contrario, per favore dimmi un altro modo per fare ciò di cui ho bisogno.
posta Skaidar 01.04.2015 - 11:12
fonte

2 risposte

1

npinti fornisce un buon esempio di codice, ma in generale quello che stai facendo è uno scenario molto comune. Il server che stai cercando di creare è un servizio web di base, spesso in questi giorni utilizzando un RESTful Modello API su HTTP. Il client riunisce alcuni dati in un formato predefinito di tua scelta e li trasmette a un URL di tua scelta sul server. Il server può inviare messaggi al client usando qualcosa come WebSockets , che funzionano come semplici connessioni TCP / IP ma possono passare attraverso la maggior parte firewall.

    
risposta data 01.04.2015 - 21:31
fonte
0

Devi chiudere lo stream di connessione dal tuo client. Il ciclo while del server non verrà terminato finché il client non chiude la connessione.

Per quanto riguarda la tua domanda su come sapere cosa sta mandando il tuo cliente, potresti usare una serie iniziale di byte per indicare che stai inviando. Pertanto, se invii 0x00 , invii un file, se invii 0x01 , invii un elenco di array e così via.

Per il primo punto, potresti farlo in questo modo:

using NetworkStream stream = client.GetStream()
    stream.Write(file, 0, fileBuffer.GetLength(0));

Per il secondo, puoi provare qualcosa del genere (NOTA: questo codice non è compilato, ma dovrebbe indirizzarti nella giusta direzione):

byte[] transType = new byte[] {(byte)0};   //Assuming that 0 means you are sending a file.
byte[] file = File.ReadAllBytes(Constants.TARGET_PATH_LOGS + "squad.jpg");
byte[] transData = new byte[transType.Length + file.Length]
transType.CopyTo(transData, 0);

file.CopyTo(transData, tansType.Length);
byte[] fileBuffer = new byte[file.Length];
using NetworkStream stream = client.GetStream()
        stream.Write(file, 0, fileBuffer.GetLength(0));

Nel tuo server:

bool isFirst = true;
TransmissionType transmissionType = TransmissionType.Unknown;   //This is an enumeration you can create.

while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) 
{
    if(isFirst) 
    {
        isFirst = false;
        byte transType = buffer[0];
        switch(transType)
        {
            case (byte)0: 
            { 
                transmissionType = TransmissionType.File;
                byte[] bufferToWrite = new byte[buffer.Length - 1];
                Array.Copy(buffer, 1, bufferToWrite, bufferToWrite.Length);
                fileStream.Write(bufferToWrite, 0, read);
                totalRead += read;
                continue;
            }
            ... //Other Cases
        }
    }

    switch(transmissionType)
    {
        case TransmissionType.File :
        {
            fileStream.Write(buffer, 0, read);
            totalRead += read;
            break;
        }
    }                
}
    
risposta data 01.04.2015 - 11:20
fonte

Leggi altre domande sui tag