La natura degli stream che sono stati costruiti su socket è che si dispone di una pipeline aperta che trasmette e riceve dati fino alla chiusura del socket.
Tuttavia, a causa della natura delle interazioni client/server, questa pipeline non è sempre garantita per la lettura del contenuto. Il client e il server devono accettare di inviare il contenuto attraverso la pipeline.
Quando si prende lo Stream
abstraction in .NET e lo si sovrappone al concetto di socket, si applica ancora il requisito per un accordo tra client e server; puoi chiamare lo Stream.Read
tutto ciò che desideri, ma se la presa su cui è collegato il tuo Stream
sull'altro lato non sta inviando il contenuto, la chiamata attenderà solo che ci sia del contenuto.
Ecco perché esistono protocolli. Al loro livello più elementare, aiutano a definire quale sia il messaggio completo che viene inviato tra due parti. Solitamente, il meccanismo è qualcosa sulla falsariga di:
- Un messaggio lunghezza prefissato in cui il numero di byte da leggere viene inviato prima il messaggio
- Un modello di caratteri utilizzato per indicare la fine di un messaggio (questo è meno comune a seconda del contenuto che viene inviato, la più arbitraria qualsiasi parte del messaggio può essere, meno è probabile che questo sarà usato)
detto questo non si sta aderendo alla sopra; la tua chiamata a Stream.Read
sta dicendo "leggi 1024 byte" quando in realtà, potrebbero non esserci 1024 byte da leggere. In questo caso, la chiamata a Stream.Read
verrà bloccata fino a quando non viene compilato.
Il motivo per cui la chiamata a Thread.Sleep
probabilmente funziona è perché nel momento in cui passa un secondo, il Stream
ha 1024 byte su di esso da leggere e non blocca.
Inoltre, se si desidera veramente leggere 1024 byte, non è possibile presumere che la chiamata a Stream.Read
popolerà 1024 byte di dati. Il valore restituito per il metodo Stream.Read
indica quanti byte sono stati effettivamente letti. Se hai bisogno di più per il tuo messaggio, devi effettuare ulteriori chiamate allo Stream.Read
.
Jon Skeet wrote up the exact way to do this se si desidera un campione.
Il client ha bisogno di un modo per scoprire quando il server è finito (ad esempio, un prefisso di lunghezza per una sequenza di terminazione speciale) – SLaks
Provare a utilizzare StreamReader http://msdn.microsoft.com/en-us/library/system. io.streamreader.aspx – David
In che modo StreamReader può essere d'aiuto? Non sa neanche quando il server è finito. –