Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Networkstream.read()

Tags:

c#

.net

sockets

How does read(buffer, offset, length) actually work, if i pass the length to read as 32, does that mean that it would keep blocking till it receives the 32 bytes?

I understand it would return and exception or 0 in case of socket exception or if the connection is closed, respectively.

what if the sender only sends 31 bytes , would read continue to block? if that is true, does it mean that read would always return the integer that is equal to length passed to it? and also how cnan i control the timeout if the remaining 1 byte does not come after certain time.

Important and yet not answered

In contrast, what if the sender sends 32 byte , does that assure that read would block until all 32 are received or can it come out without reading all the 32 bytes.

like image 775
Kazoom Avatar asked Sep 01 '09 22:09

Kazoom


Video Answer


1 Answers

No, it will not block. The Read operation reads as much data as is available, up to the number of bytes specified by the size parameter. Source: http://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.read.aspx

Given it will not wait for that extra 1 byte, if you are expecting it, you should implement a loop to continue reading the stream. You can exit the loop however you feel best.


UPDATE: I was wrong when I stated "There's no blocking at all. If no data is available for reading, the Read method returns 0", but I was correct when I stated that it wouldn't block waiting to fill the entire buffer which it the scenario described in Kazoom's question.

Updated to demonstrate that NetworkStream.Read blocks waiting for the first byte, but does not block waiting to fill the entire buffer.

Create to console projects

On one end, you have the listener:


IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345);
TcpListener listener = new TcpListener(ep);
listener.Start();
TcpClient client = listener.AcceptTcpClient();
NetworkStream s = client.GetStream();
byte[] buffer = new byte[32];
Console.WriteLine(s.Read(buffer, 0, 32));
Console.WriteLine("Press any key to continue...");
Console.Read();

On the other end, we send only one byte:


IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345);
TcpClient client = new TcpClient();
client.Connect(ep);
client.GetStream().Write(new byte[] { 60 }, 0, 1);
Console.WriteLine("Press any key to continue...");
Console.Read();

Both sides will run until they reach Console.Read(). Notice that the listener does not block on Read.

The listener will print "1"

like image 70
Alfred Myers Avatar answered Oct 21 '22 23:10

Alfred Myers