Domanda

Sto cercando di scrivere un semplice client SNPP (Simple Network Paging Protocol) usando i socket. Tutto sembra funzionare bene, tranne una piccola incoerenza tra i server.

Quando invio un comando, devo leggere la risposta, che di solito è un singolo blocco di dati. Tuttavia, il server SNPP di Sprint invia risposte in due parti. Il primo blocco di dati è la prima cifra del codice di stato. Il secondo pezzo è il resto. Ad esempio, quando provo a ricevere il "220 Gateway pronto" risposta, arriva così:

2

Devo inviare un altro comando vuoto per recuperare il resto:

20 Gateway ready

Per il momento, sto usando:

byte[] buffer = new byte[256];
socket.Receive(buffer);

Come posso assicurarmi di ricevere tutti i dati disponibili dopo aver emesso un comando senza allocare un buffer separato per ogni blocco di dati?

È stato utile?

Soluzione

Per le risposte in blocco ti consiglio di leggere i dati in questo modo:

using (var resultStream = new MemoryStream())
{
    const int CHUNK_SIZE = 2 * 1024; // 2KB, could be anything that fits your needs
    byte[] buffer = new byte[CHUNK_SIZE];
    int bytesReceived;
    while ((bytesReceived = socket.Receive(buffer, buffer.Length, SocketFlags.None)) > 0)
    {
        byte[] actual = new byte[bytesReceived];
        Buffer.BlockCopy(buffer, 0, actual, 0, bytesReceived);
        resultStream.Write(actual, 0, actual.Length);
    }

    // Do something with the resultStream, like resultStream.ToArray() ...
}

Altri suggerimenti

Prova a controllare la proprietà Socket.Available per determinare se devi chiamare di nuovo Ricevi.

Penso di aver capito la tua domanda. Questo sovraccarico di Socket.Receive consente di passare un numero intero per specificare una posizione di offset per iniziare a posizionare i dati. Se hai 1 byte, alla prima chiamata come nel tuo esempio, puoi chiamare questo sovraccarico con un offset di 1 e usare lo stesso buffer.

Socket.Receive restituisce un numero intero che è il numero di byte che sono stati ricevuti. Puoi verificare se questo è 1 e chiamare nuovamente Ricevi .

byte[] buffer = new byte[256];
int len = socket.Receive(buffer);

if (len == 1)
  socket.Receive(buffer, 1, buffer.Length - 1, SocketFlags.None);

Tutti,

Quando un web server invia dati in "blocchi" " precede ogni blocco con la sua lunghezza (come una stringa che indica il valore esadecimale).

chunk-size [; chunk-extensions] chunk-data

ad es .: per bloccare 15 byte:

F; 123456789ABCDEF

Il problema più grande con la ricezione di dati HTTP da un Socket è determinare quanti dati leggere: se hai ricevuto tutti i dati disponibili e chiami di nuovo il metodo Recieve, il metodo Recieve si bloccherà fino a quando il socket remoto non invierà più dati, quale per una connessione HTTP / 1.0 non accadrà mai.

È necessario implementare un lettore che avvolge il socket; dovrebbe ricevere i dati in un buffer e fornire un codice "ReadLine" metodo che legge il contenuto del buffer fino a quando non legge 13 seguito da 10 (CRLF)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top