C# Networkstream.read()

后端 未结 3 1908
忘了有多久
忘了有多久 2021-02-08 11:48

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 unde

相关标签:
3条回答
  • 2021-02-08 12:16

    The question about the timeout would appear to still be unanswered.

    The answer is that you can set stream.ReadTimeout and stream.WriteTimeout, where stream is your NetworkStream object. This handles the blocking case of no response at all. Without setting these values, the stream will wait indefinitely.

    0 讨论(0)
  • 2021-02-08 12:20

    It will block until it receives 32 bytes, or the connection is closed. The async methods BeginRead() and EndRead() should be used to provide non-blocking reads.

    Here is some example code clearly demonstrating the blocking effect.

       Socket one = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        Socket two = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    
        IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345);
    
        one.Bind(ep);
        one.Listen(1);
        two.Connect("127.0.0.1", 12345);
        one = one.Accept();
    
        NetworkStream s = new NetworkStream(two);
        byte[] buffer = new byte[32];
        s.Read(buffer, 0, 32);
    

    Edit

    Even though this code produces the blocking effect, it's only because of NetworkStream's implementation of Stream's abstract Read() method (which must be overridden). The documentation on Stream.Read() states this:

    Implementations return the number of bytes read. The return value is zero only if the position is currently at the end of the stream.

    Which is why the code blocks when NO data has been received AND the end of the stream has not been reached. It also goes on to say:

    The implementation will block until at least one byte of data can be read, in the event that no data is available. Read returns 0 only when there is no more data in the stream and no more is expected (such as a closed socket or end of file). An implementation is free to return fewer bytes than requested even if the end of the stream has not been reached.

    0 讨论(0)
  • 2021-02-08 12:38

    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"

    0 讨论(0)
提交回复
热议问题