Как правильно использовать метод `Read ()`, который записывает в буфер фиксированного размера (здесь `TcpClient`)? - PullRequest
2 голосов
/ 06 апреля 2011

Я пытаюсь прочитать данные из TcpClient, вот как я это делаю:

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();

Проблема в том, что моя строка не имеет длины 8192 (что являетсязначение client.ReceiveBufferSize), и поэтому я добавляю много \0 в мой StringBuilder.

Как я могу получить только точный объем данных?

1 Ответ

9 голосов
/ 06 апреля 2011
int readCount;
while ((readCount = ns.Read(data, 0, client.ReceiveBufferSize)) != 0)
{
    dataString.Append(Encoding.UTF8.GetString(data, 0, readCount));
}

РЕДАКТИРОВАТЬ:

Как указывает mg30rg в комментариях, этот подход уязвим для клиентов, которые подключаются, а затем немедленно отключаются.Лучше проверить свойство DataAvailable перед вызовом Read();в противном случае поток, очевидно, будет блокироваться на неопределенное время.

Кроме того, свойство Connected, по-видимому, будет возвращать true до тех пор, пока не будет вызван Read() или Write(), поэтому вы не сможете обнаружить эту ситуацию с помощьюиспользуя это свойство.

...