Results 1 to 6 of 6

Thread: [RESOLVED] [TCP] What to do with empty buffer?

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Mar 2012
    Posts
    67

    Resolved [RESOLVED] [TCP] What to do with empty buffer?

    I have now successfully written a tcp client and server thingy, following some tutorials.

    But I have one question, I am reading data from "the stream" into a 4096 sized buffer. If the message is shorter than that, for example just a serialized string, the rest of the buffer is just zeros.

    The tutorial handled the zeros as "keep-alive" messages. Well, it works, but then the program will have to read 4 bytes at a time and check if they converted to an int is zero (I am using "length-framed" writing/reading). That takes some time if there are like 2k+ bytes that needs to be looped through, when other messages just need to wait in queue.

    I am sorry if this explanation got messy, but to simplify it:

    I have an array of bytes, and I want the program to detect when there are no data left in that array (just zeros), so I can trash it. Is that possible?

    Any other suggestions on how my networking should work are welcome too since I am new in this area of programming

  2. #2

    Thread Starter
    Lively Member
    Join Date
    Mar 2012
    Posts
    67

    Re: [TCP] What to do with empty buffer?

    I have solved it for now, by doing this:

    If I am looking for a length buffer (containing the length of the message), and I can't find a valid length (>0) in the next 4 bytes I analyze, I report that back to the method that holds the complete 4k buffer I last read from the stream so that method can discard the rest of the data.

    I am not sure if this is the right way to solve it, but it works.
    I would be really happy to receive some feedback on how to improve/change this solution

    Since this solution has at least one con:

    If the sender would fail with something and write 4 empty bytes (or more than that) and then write the data it wanted to send, the whole message would be discarded since I throw away the whole 4k read buffer if some bytes fail.

  3. #3
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: [TCP] What to do with empty buffer?

    When you read from a stream, you pass it a buffer and tell it how man bytes it is allowed to read from the stream and write into the buffer (this is generally the length of the buffer).

    The Read method returns the number of bytes that were actually read from the stream and written into the buffer. You need to save this return value into a variable and then only read that many bytes out of the buffer.

    Remember that the buffer only holds zeroes as long as nothing has been written to that element of the buffer before. For example, if the first call to read reads 1024 bytes from the stream, the first 1024 elements of the buffer will be "non-zero" (they may in fact still be zero if the stream had any zero bytes in it, obviously).

    If the second call only reads 256 bytes, the first 1024 bytes will still be non-zero. The call to Read doesn't set any unused elements of the buffer back to zero.

    I don't know what this "length-framed" technique is, could you provide a link to the tutorial you're referring to? What I can tell you is that you are not guaranteed to read from the stream in the same "chunks" that you wrote to the stream from the other computer, so you need to be prepared to read part of a message, and also more than one message, in a single call to Read.

  4. #4

    Thread Starter
    Lively Member
    Join Date
    Mar 2012
    Posts
    67

    Re: [TCP] What to do with empty buffer?

    Wow I feel so dumb.

    Here:
    http://nitoprograms.blogspot.se/2009...x-message.html
    and this:
    http://www.switchonthecode.com/tutor...ded-tcp-server

    As you can see in the nito site, he stores the amount read, but he never passes that count on -.-'
    Anyway, I have modified the code now to do so

    csharp Code:
    1. private void HandleClient(object client)
    2.         {
    3.             TcpClient tcpClient = (TcpClient)client;
    4.             NetworkStream clientStream = tcpClient.GetStream();
    5.  
    6.             byte[] data = new byte[4096];
    7.             while (true)
    8.             {
    9.                 int bytesRead = 0;
    10.                 try
    11.                 {
    12.                     //blocks until a client sends a message
    13.                     bytesRead = clientStream.Read(data, 0, 4096);
    14.                 }
    15.                 catch
    16.                 {
    17.                     //a socket error has occured
    18.                     break;
    19.                 }
    20.  
    21.                 if (bytesRead == 0)
    22.                 {
    23.                     //the client has disconnected from the server
    24.                     break;
    25.                 }
    26.  
    27.                 //data has been received, process it
    28.                 ProcessData(data, bytesRead);
    29.             }
    30.  
    31.             tcpClient.Close();
    32.         }
    33.  
    34.         private void ProcessData(byte[] data, int count)
    35.         {
    36.             int i = 0;
    37.             while (i != count)
    38.             {
    39.                 int bytesAvailble = count - i;
    40.                 if (dataBuffer != null)
    41.                 {
    42.                     //We're reading into the data buffer
    43.                     int bytesRequested = count - bytesReceived;
    44.  
    45.                     //Copy the incoming bytes into the buffer
    46.                     int bytesTransferred = Math.Min(bytesRequested, bytesAvailble);
    47.                     Array.Copy(data, i, dataBuffer, bytesReceived, bytesTransferred);
    48.                     i += bytesTransferred;
    49.  
    50.                     //Notify read completion
    51.                     ReadCompleted(bytesTransferred);
    52.                 }
    53.                 else
    54.                 {
    55.                     //We're looking for the length buffer
    56.                     int bytesRequested = lengthBuffer.Length - bytesReceived;
    57.                     int bytesTransferred = Math.Min(bytesRequested, bytesAvailble);
    58.  
    59.                     Array.Copy(data, i, lengthBuffer, bytesReceived, bytesTransferred);
    60.                     i += bytesTransferred;
    61.  
    62.                     ReadCompleted(bytesTransferred);
    63.                 }
    64.             }
    65.         }

    I haven't copy and pasted anything, though I have written the same lines since I was following his tutorial

    Oh and I am taking care of the half-message situations in the later methods, as the second tutorial does

  5. #5
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: [TCP] What to do with empty buffer?

    I found a link to the nito blog from another thread you posted. The fixed-length stuff is about how to break apart and stitch back together the multiple/partial reads. It's the logical layer above the stream reading code.

    Good luck with the rest of it, you probably should go back and read the previous post on the nito site regarding why why you need to do this, if you haven't already.

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Mar 2012
    Posts
    67

    Re: [TCP] What to do with empty buffer?

    Oh yeah I read that "discussion" over at codeproject before, always interesting to know how stuff works

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width