C# – How to properly use a `Read()` method that writes into a fixed size buffer (here `TcpClient`)

c++connectiontcpclienttcplistener

I am trying to read the data from a TcpClient, here is how I am doing it:

var client = tcpListener.AcceptTcpClient();
var data = new byte[client.ReceiveBufferSize];

StringBuilder dataString = new StringBuilder();
using (var ns = client.GetStream())
{
    while (ns.Read(data, 0, client.ReceiveBufferSize) != 0)
    {
        dataString.Append(Encoding.UTF8.GetString(data));
    }
}
client.Close();

The problem is that my string does not have a length of 8192 (which is the value of client.ReceiveBufferSize) and because of that I am appending a lot of \0 in my StringBuilder.

How can I get only the exact amount of data?

Best Solution

int readCount;
while ((readCount = ns.Read(data, 0, client.ReceiveBufferSize)) != 0)
{
    dataString.Append(Encoding.UTF8.GetString(data, 0, readCount));
}

EDIT:

As mg30rg points out in the comments, this approach is vulnerable to clients that connect and then immediately disconnect. It is better to check the DataAvailable property before calling Read(); otherwise the thread will apparently block indefinitely.

Also, the Connected property will apparently return true until Read() or Write() is called, so you won't be able to detect this situation by using that property.