TcpClient Socket Blocking Problems

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Christopher H. Laco

    #1

    TcpClient Socket Blocking Problems

    I'm having a problem with the TcpClient that I can only conclude is
    either a feature, or a complete misunderstandin g of the docs on my part.

    In a nutshell, I'm simply performing the following sequence with a server:

    connect
    write(50 bytes)
    read(2002 bytes)
    write(50 bytes)
    read(2002 bytes)
    write(50 bytes)
    read(2002 bytes)
    disconnect

    At random times, one of the read sequences will read only 1460 bytes
    instead of 2002 bytes. The reaminder, 542 bytes, just happens to fall on
    a packet boundry. More on that later.

    Now, for the sake of this argument, the number of times the write/read
    sequence could happen per connection is unknown. Could be once; could be
    20 times.

    Now for some somewhat real code...

    TcpClient client = new TcpClient();


    client.NoDelay = true;
    client.Client.B locking = true;
    client.Connect( "remote_server" , 3456);

    for (int i = 1; i++; i <= 3) {
    Byte[] outputbuffer;
    NetworkStream stream;

    outputbuffer = Encoding.ASCII. GetBytes("50 bytes of data...");
    stream = this.GetStream( );
    stream.Write(ou tputbuffer, 0, outputbuffer.Le ngth);

    Byte[] inputbuffer;
    inputbuffer = new Byte[2002];
    Debug.WriteLine (stream.Read(in putbuffer, 0,inputbuffer.L ength));
    }


    client.Close();


    Now, sometimes when I run this, I get:
    2002
    2002
    1460
    Or this:
    1460
    2002
    2002
    OR this:
    2002
    1460
    2002

    Clearly, Socket.Blocking is not doing what I expect.
    Sockst docs say that BLocking is on by default, so shouldn't it be doing
    so, or is this a matter of the NetworkStream not doing something right?

    Should I be using the Socket.Send/Receive methods instead?

    At this point, I'm quite confused about the interaction of Socket vs.
    NetworkStream within the TcpClient.

    Thanks,
    -=Chris
  • Christopher H. Laco

    #2
    Re: TcpClient Socket Blocking Problems

    Christopher H. Laco wrote:
    [snip][color=blue]
    > Now, sometimes when I run this, I get:
    > 2002
    > 2002
    > 1460
    > Or this:
    > 1460
    > 2002
    > 2002
    > OR this:
    > 2002
    > 1460
    > 2002[/color]

    I forgot the mention that in the cases where NetworkSteam.Re ad returns
    1460 instead of the requested 2002, the full 2002 bytes have indeed been
    sent by the server and seen by the network card as witnessed by a good
    dose of Ethereal packet sniffing.

    In those cases, the 1460 is the first of two packets, and the second
    packet contains the remaining 542 bytes of data.

    -=Chris

    Comment

    • Sunny

      #3
      Re: TcpClient Socket Blocking Problems

      Hi,

      stream.Read does not obey that all data will be received. You have to
      loop Read untill it returns 0.

      Try something like this:

      byte[] buffer = new byte[2002];
      int bytesread = 0;

      while (stream.Read(bu ffer, bytesread, buffer.Length - bytesread) > 0);

      Note, I haven't tested this exact code, but it should work, or at least
      it shows you the idea.

      Sunny

      In article <4fgOc.491$hI.7 8220@newssvr28. news.prodigy.co m>,
      mendlefarg@gmai l.com says...[color=blue]
      > Christopher H. Laco wrote:
      > [snip][color=green]
      > > Now, sometimes when I run this, I get:
      > > 2002
      > > 2002
      > > 1460
      > > Or this:
      > > 1460
      > > 2002
      > > 2002
      > > OR this:
      > > 2002
      > > 1460
      > > 2002[/color]
      >
      > I forgot the mention that in the cases where NetworkSteam.Re ad returns
      > 1460 instead of the requested 2002, the full 2002 bytes have indeed been
      > sent by the server and seen by the network card as witnessed by a good
      > dose of Ethereal packet sniffing.
      >
      > In those cases, the 1460 is the first of two packets, and the second
      > packet contains the remaining 542 bytes of data.
      >
      > -=Chris
      >[/color]

      Comment

      • Christopher H. Laco

        #4
        Re: TcpClient Socket Blocking Problems

        Sunny wrote:
        [color=blue]
        > Hi,
        >
        > stream.Read does not obey that all data will be received. You have to
        > loop Read untill it returns 0.
        >
        > Try something like this:
        >
        > byte[] buffer = new byte[2002];
        > int bytesread = 0;
        >
        > while (stream.Read(bu ffer, bytesread, buffer.Length - bytesread) > 0);
        >
        > Note, I haven't tested this exact code, but it should work, or at least
        > it shows you the idea.
        >
        > Sunny[/color]

        Yeah, I knew about the loop trick. There seems to be some dissention
        about whether to loop on DataAvailable or on the int count returned from
        Read. Although, I'd think the latter is safer.

        I guess I'm more curious as to WHY the NetworkStream doesn't really
        honor socket blocking in the sence of waiting until I have all the bytes
        requested.

        -=Chris

        Comment

        • Sunny

          #5
          Re: TcpClient Socket Blocking Problems

          Hi,

          In article <410a5b0b$1@sum mitproxy.summit .network>, mendlefarg@gmai l.com
          says...[color=blue]
          > I guess I'm more curious as to WHY the NetworkStream doesn't really
          > honor socket blocking in the sence of waiting until I have all the bytes
          > requested.
          >
          > -=Chris[/color]

          Because the network streem does not support Length property. So there is
          no way to query it about the content. You just read until it ends.

          in very basic terms:
          The socket is the communication part only. The stream is the content.
          The socket only provides access to the stream, it does not deal with its
          content. So it blocks only until there is some stream, and after that if
          passes that stream to you for reading.

          Sunny

          Comment

          Working...