How does NetworkStream work bi-directionally?

I have read the Tcp Echo Server example and some things are not clear to me.

TcpClient client = null;
NetworkStream netStream = null;

try {
  client = listener.AcceptTcpClient(); 
  netStream = client.GetStream();

  int totalBytesEchoed = 0;
  while ((bytesRcvd = netStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0) {
    netStream.Write(rcvBuffer, 0, bytesRcvd);
    totalBytesEchoed += bytesRcvd;
  }

  netStream.Close();
  client.Close();
} catch {
  netStream.Close();
}

      

When the server receives the packet (while loop), it reads the data into rcvBuffer and writes it to the stream.

What confuses me is the chronological order of messages in communication. Whether the data that was written using netStream.Write () is sent immediately to the client (which might even be sent) or only after the data that has already been written to the stream (by the client) has been processed.

The next question might even clarify the previous one: if the client sends some data by writing to a stream, the data is moved to the server side message queue, waiting to be read, so the stream is actually "empty"? This explains why the server can write to the stream right away - because the data that comes from the stream is actually buffered elsewhere ...?

+2


source to share


3 answers


Hint: Calling the NetworkStream.Read method is blocking in this example.

The book is absolutely correct: raw access to TCP streams does not imply any additional "chunking", and in this example, for example, one byte can be easily processed at a time. However, performing reads and writes in batches (usually with open buffers) can provide more efficient processing (often as a result of fewer system calls). The network layer and network equipment also use their own buffer shapes.

There is really no guarantee that the data written with Write () will actually be written before the more verbose read () is done: even if the data is cleared at one level, it does not mean that it turns red at another. and there is absolutely no guarantee that the data is returned to the client. Higher layer protocols are used here.



With this echo example, the data is simply pushed as fast as it can be. Both Write and Read will block based on the underlying network stack (specifically the send and receive buffers), each with its own sequence of buffers.

[This makes things a little easier - you can always look at TCP [protocol], which imposes transmission characteristics on the actual packet flow.]

+2


source


A TCP connection is, in principle, full duplex. This way you are dealing with two separate channels and yes, both sides can write at the same time.



+2


source


You are correct that technically you are not reading the bits from the wire when doing the Read () operation. You are basically reading buffered data (chunks received by TCP and placed in the correct order). When sending, you can Flush (), which in theory should send data immediately, but modern TCP stacks have a bit of logic on how to collect data in appropriate size packets and wrap it into a wire.

As Henk Holterman explained, TCP is a full duplex protocol (if supported by all underlying infrastructures), so sending and receiving data is more when the server / client is reading and writing data. It is not like when the server sends data, the client will read it immediately. The client can send its own data and then execute Read (), in which case the data will remain in the network buffer for longer and can be discarded after a while when no one wants to read it. At least I experienced this when dealing with my version of the server / client supa dupa library (-.

+1


source







All Articles