Search code examples
c#socketstcpclient

Getting junk data in messages being sent with TcpClient and TcpListener


I have several other pieces of network code running using identical code and I have never seen this before. The remaining bytes in the receiving buffer are getting filled with \0\0\0\0\0\0\0\0\0\0\

I have seen this asked a few times, but there has never been an answer.

TcpListener tlist = new TcpListener(IPAddress.Parse(ip.ToString()), 27275);

Once there is a connection. . .

byte[] byData = new byte[textBox.Text.Length];
byData = System.Text.Encoding.UTF8.GetBytes(textBox.Text);
client.Send(byData, 0, byData.Length, 0);

And the receiving end:

byte[] bufferRec = new byte[56];
tc.Client.Receive(bufferRec, 0, 56, 0);
string output = Encoding.UTF8.GetString(bufferRec);

The buffer size I typically use is 256, and it is rare I am actually sending/receiving 256 bytes of data, but I never see those remaining bytes get filled with junk data, only in this case.

Edit: I can of course simply parse out the junk data, but it is still strange behaviour given there is no reason for it.


Solution

  • You're ignoring the return value of Socket.Receive which tells you how many bytes have been read - which is just like ignoring the return value of Stream.Read. So your buffer contains more bytes than you've actually received, and your string therefore includes a lot of U+0000 characters. For example, taking a buffer of length 16 and the text "HELLO"

    buffer: 48 45 4C 4C 4f 00 00 00 00 00 00 00 00 00 00 00
    Return value: 5 (5 bytes received)
    Encoding.UTF8.GetBytes(buffer): "HELLO\0\0\0\0\0\0\0\0\0\0\0"
    Encoding.UTF8.GetBytes(buffer, 0, 5): "HELLO"
    

    Basically, you should only use the part of the buffer which contains data which has been received. You should also not assume that a single call to Receive (or Stream.Read) will read all the data in one go, even if your buffer is big enough to receive it. TCP is a streaming protocol, so all the normal caveats around streaming apply. If you're trying to write a message-oriented protocol, you'll need to layer that on top of TCP (e.g. by having a "header" part which indicates how much data is in the next message).

    As an aside, it's rarely a good idea to use the underlying socket directly from TcpClient - the main point of using it is that you can use higher level abstractions such as GetStream().