Domanda

Quando si leggono i dati in rete, si specifica un buffer in cui ricevere i dati in:

byte[] b = new byte[4096];
socket.Receive(b);

Ora il mio primo pensiero è ovviamente quello di riutilizzare il buffer di ricezione dichiarandolo come variabile membro della classe. Il mio prossimo problema è che non ho ricevuto tutti i dati che mi aspetto, quindi ho bisogno di bufferizzare i miei dati. Questo è facile da realizzare tenendo traccia del conteggio dei byte ricevuti e specificando l'offset:

socket.Receive(m_ReceiveBuffer, count, m_ReceiveBuffer.Length - count);

Ora, il problema qui è che, se non è ancora sufficiente, suppongo di dover aumentare il buffer, il che significa copiare la memoria e continuare a ricevere in questo buffer. Supponendo che qualcosa sia andato storto, questo buffer avrebbe continuato a crescere e, se fossero stati ricevuti messaggi abbastanza grandi, il sistema avrebbe esaurito la memoria.

Qualche idea su come gestirlo correttamente? Esiste un modo migliore per ricevere i dati che riempire, copiare, crescere, riempire, copiare, crescere di cui sto parlando?

È stato utile?

Soluzione

leggi in grossi pezzi:

const int ChunkSize = 4096;
int bytesRead;
byte[] buffer = new byte[ChunkSize];
while ((bytesRead = socket.Receive(buffer, 0, ChunkSize, SocketFlags.None)) > 0)
{
    byte[] actualBytesRead = new byte[bytesRead];
    Buffer.BlockCopy(buffer, 0, actualBytesRead, 0, bytesRead);
    // Do something with actualBytesRead, 
    // maybe add it to a list or write it to a stream somewhere
}

Altri suggerimenti

Prima di iniziare con SYstem.Net.Sockets.Socket, sei sicuro di non poter utilizzare System.Net.Sockets.TcpClient (o UdpClient) che fa funzionare tutto il buffer disordinato e lo trasforma in un sistema facilmente gestibile lo streaming?

Altrimenti, ricorda che la quantità di dati che ricevi non deve essere uguale a quella richiesta, quindi dovresti sempre guardare il valore di ritorno dalla funzione di ricezione. E, l'unico modo per non esaurire la memoria è in realtà elaborare ciò che ricevi.

Innanzitutto, separa il codice nella ricezione dei dati e nell'elaborazione dei dati. Il buffer di ricezione deve contenere solo i dati fino a quando il codice non ha la possibilità di copiarli nell'area di elaborazione. L'area di elaborazione è dove determinerai se hai ricevuto abbastanza dati per fare qualcosa di utile. Non lasciare i dati nella rete ricevere buffer fino a quando ciò non accade. Per quanto riguarda il buffer di ricezione della rete, penso che l'utilizzo di un buffer circolare ti aiuterà con l'idea di riutilizzare un buffer. Spero che tu abbia un'idea delle dimensioni del messaggio. Ciò contribuirà a determinare la dimensione del buffer. Se asserisci (o qualcosa di simile) quando i puntatori di lettura e scrittura del buffer circolare si incontrano, aumenta la dimensione del buffer. Una volta che la dimensione del buffer è abbastanza grande, dovresti essere in grado di leggere abbastanza dati dal buffer nel codice di elaborazione a una velocità abbastanza veloce da non far traboccare il buffer circolare.

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