none
Data reading from TCP socket is always available, even after read. RRS feed

  • Question

  • Hi, I've got a program which runs a TcpClient and sends two messages to a TcpListener and then exits. The TcpListener reads data from the NetworkStream when NetworkStream.DataAvailable=True but it seems that DataAvailable is always = True.

    I uploaded my project as a picture. Just right click and save the link WindowsApplication1 as a zip file.

    WindowsApplication1.jpg

    Thanks.
    • Edited by M4DH4X3R Saturday, August 17, 2013 2:03 AM
    Saturday, August 17, 2013 1:55 AM

Answers

  • DataAvailable certainly works fine but you're misusing it and more generally, the NetworkStream.

    NetworkStream.Read doesn't necessarily return the number of bytes you have requested, it may return less bytes. For example you may ask for 200 kbytes but if only 1500 bytes are available in the socket buffer then that's all you'll get

    In your Read function you're trying to read the image from the stream but you don't check if you really got all the image. Then Timer1_Tick method is called again DataAvailable will be true again because you didn't read all the image and more bytes have arrived on the network. Now you're calling Read again and try to parse some image bytes as Integer. Your StringToInteger doesn't check if the string is really an Integer and returns a bogs value. The value can be very large and then the attempt to allocate a very large array for the image fails with an OutOfMemoryException.

    So, always check the return of NetworkStream.Read. If it returns less bytes than you requested you have to call NetworkStream.Read again for the remaining bytes.

    And there's another problem with your code: you're sending the image as text. Don't do that, images are binary data, attempting to treat random binary data as text may result in bogus results like image bytes being changed. Replace ReadAllText with ReadAllBytes and get rid of ASCII.GetString/GetBytes for image data.

    Saturday, August 17, 2013 8:03 AM
    Moderator

All replies

  • DataAvailable certainly works fine but you're misusing it and more generally, the NetworkStream.

    NetworkStream.Read doesn't necessarily return the number of bytes you have requested, it may return less bytes. For example you may ask for 200 kbytes but if only 1500 bytes are available in the socket buffer then that's all you'll get

    In your Read function you're trying to read the image from the stream but you don't check if you really got all the image. Then Timer1_Tick method is called again DataAvailable will be true again because you didn't read all the image and more bytes have arrived on the network. Now you're calling Read again and try to parse some image bytes as Integer. Your StringToInteger doesn't check if the string is really an Integer and returns a bogs value. The value can be very large and then the attempt to allocate a very large array for the image fails with an OutOfMemoryException.

    So, always check the return of NetworkStream.Read. If it returns less bytes than you requested you have to call NetworkStream.Read again for the remaining bytes.

    And there's another problem with your code: you're sending the image as text. Don't do that, images are binary data, attempting to treat random binary data as text may result in bogus results like image bytes being changed. Replace ReadAllText with ReadAllBytes and get rid of ASCII.GetString/GetBytes for image data.

    Saturday, August 17, 2013 8:03 AM
    Moderator
  • Thanks man, it works now.
    Sunday, August 18, 2013 11:35 PM