2013-03-20 18 views
8

Domanda per principianti di nuovo: tipo di follow-up per una domanda che ho chiesto non molto tempo fa.Quando Socket.Receive restituisce i dati?

Sto cercando di capire questo tutorial socket sincrono http://msdn.microsoft.com/en-us/library/6y0e13d3.aspx, in particolare una sola riga nel codice qui sotto.

DOMANDA: Voglio essere sicuro di capire il flusso del programma. Quando il esegue handler.Rice (byte) restituisce? Restituisce e memorizza il numero di byte ricevuti in int bytesRec ** quando "overflow" e ha ricevuto più di 1024 byte? ** E se è così, e questo può sembrare sciocco, cosa succede se arrivano PIÙ byte mentre memorizza i 1024 byte nella variabile * dati * e non stai ascoltando più byte che potrebbero arrivare in quel momento? O non dovrei preoccuparmi di questo e lasciare che .net ci prenda cura di questo?

Socket handler = listener.Accept(); 
data = null; 

// An incoming connection needs to be processed. 
while (true) { 
    bytes = new byte[1024]; 
    int bytesRec = handler.Receive(bytes); 
    // My question is WHEN does the following line 
    // get to be executed 
    data += Encoding.ASCII.GetString(bytes,0,bytesRec); 
    if (data.IndexOf("<EOF>") > -1) { 
     break; 
    } 
} 

risposta

10

Quando non handler.Receive (byte) tornare?

Documentazione:

Se non sono disponibili dati per la lettura, il metodo di ricezione bloccherà finché i dati non è disponibile, a meno che un valore di timeout è stato impostato utilizzando Socket.ReceiveTimeout. Se il valore di timeout è stato superato, la chiamata Ricevi genererà un SocketException. Se si è in modalità non bloccante, e non vi sono dati disponibili nel buffer dello stack del protocollo, , il metodo di ricezione verrà completato immediatamente e verrà generata una SocketException . È possibile utilizzare la proprietà Available per determinare se i dati sono disponibili per la lettura. Quando Disponibile è diverso da zero, ritentare l'operazione di ricezione .


vuol tornare e memorizzare il numero di byte ricevuti in int bytesRec quando "overflow" e ha ricevuto più di 1024 byte?

No, restituisce sempre il numero di byte letti. In caso contrario, come è possibile sapere quale parte di bytes contiene dati significativi e quale parte di essa è rimasta inutilizzata?

È molto importante capire come prese funzionano tipicamente: byte possono essere arrivando in pacchetti, ma per quanto riguarda il ricevitore concerne ogni byte dovrebbe essere considerata indipendentemente. Ciò significa che non vi è alcuna garanzia che si ottengano i byte nei blocchi che il mittente li ha inviati e, naturalmente, non vi è alcuna garanzia che ci siano dati sufficienti per riempire il buffer.

Se si desidera elaborare solo i dati in entrata in blocchi da 1024 byte, è responsabilità dell'utente continuare a chiamare Receive finché non ha rilasciato in totale 1024 byte.

E se è così, e questo potrebbe sembrare stupido, cosa succede se più byte arrivano quanto sta memorizzando i 1024 byte nella variabile e non ascoltare ulteriori byte che potrebbero essere arrivando in quel momento?

Ripetiamo che Receive non memorizzerà 1024 byte nel buffer perché è la dimensione del buffer. Memorizzerà fino a 1024 byte.

Se il buffer di rete contiene più dati memorizzati internamente dallo stack di rete, verranno restituiti 1024 byte e il resto rimarrà nei buffer dello stack di rete finché non si chiama nuovamente Receive. Se Receive ha iniziato a copiare dati nel buffer e in quel momento vengono ricevuti più dati dalla rete, molto probabilmente ciò che accadrà è che questi dovranno attendere la prossima chiamata Receive.

Dopo tutto, in nessun punto nessuno ha fornito una garanzia che Receive darebbe tutto i dati che può (anche se, naturalmente, che è auspicabile ed è ciò che accade il più delle volte).

+0

Si può pensare di ricevere molto simile alla lettura da un file. Se nel file ci sono ancora abbastanza byte di dati (in questo caso stack di rete), tornerà alla dimensione del buffer in alto, altrimenti restituirà il resto dei dati (che può essere inferiore alla dimensione del buffer) . – shellster

+0

@shellster: Kind of. Ma questa descrizione ignora il fatto molto importante che lo stack di rete può decidere di consegnare i dati in qualsiasi pezzo che * sceglie *. Non c'è garanzia. – Jon

+1

@Jon grazie per una risposta superba. Quando dici "lo stack di rete può decidere di consegnare i tuoi dati in qualsiasi pezzo che sceglie" significa che il mio cliente potrebbe inviare "Scusa tesoro, non sono single ma sposato" ma il mio server potrebbe ricevere "ma sposato" prima "Scusa, tesoro"? Il codice microsoft qui sopra non esegue tale controllo degli errori ... non lo farebbe tcp/ip, quindi ricevo i dati nell'ordine corretto –

Problemi correlati