clientStream.Read возвращает неправильное количество байтов - PullRequest
2 голосов
/ 20 декабря 2011

Этот код работает:

TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[5242880];
int bytesRead;

bytesRead = clientStream.Read(message, 0, 909699);

Но это возвращает неправильное количество байтов:

bytesRead = clientStream.Read(message, 0, 5242880);

Почему? Как я могу это исправить?

(реальный размер данных - 1475186; код возвращает 11043 как число байтов)

Ответы [ 5 ]

7 голосов
/ 20 декабря 2011

Если это поток на основе TCP, то ответ таков: остальные данные просто еще не поступили.

TCP ориентирован на поток.Это означает, что нет никакого отношения между количеством вызовов Send / Write и количеством событий приема.Несколько записей могут быть объединены вместе, и отдельные записи могут быть разделены.

Если вы хотите работать с сообщениями по TCP, вам необходимо реализовать свой собственный алгоритм пакетирования поверх него.Типичные стратегии для достижения этой цели:

  1. Префикс каждого упакован по своей длине, обычно с двоичными данными
  2. Используйте последовательность разделения, такую ​​как разрыв строки.Обычно с текстовыми данными.

Если вы хотите прочитать все данные блокирующим способом, вы можете использовать цикл до тех пор, пока DataAvailable не станет true, но последующий вызов Read вернет 0.(Надеюсь, я правильно запомнил эту часть, некоторое время не занимался сетевым программированием)

2 голосов
/ 20 декабря 2011

Из MSDN:

Операция чтения считывает столько данных, сколько доступно, до количество байтов, указанное параметром размера.

т.е. Вы должны вызывать метод Read () в цикле, пока не получите все данные. Посмотрите пример кода в MSDN .

1 голос
/ 20 декабря 2011

Чтение Документации :

Этот метод считывает данные в параметр буфера и возвращает количество успешно прочитанных байтов.Если данные для чтения недоступны, метод Read возвращает 0. Операция Read считывает столько данных, сколько доступно, вплоть до количества байтов, указанного параметром size.Если удаленный хост закрывает соединение, и все доступные данные были получены, метод Read завершается немедленно и возвращает ноль байтов.

Так что это может быть из-за сбоя соединения, которое вы получаете каждый раз по-другомуномер, в любом случае вы можете проверить результат, чтобы узнать, является ли это причиной.

1 голос
/ 20 декабря 2011

Вам необходимо зациклить чтение байтов сообщения до тех пор, пока свойство Доступно на клиенте TCP или свойство DataAvailable NetworkStream не будут равны 0 (= больше не осталось байтов)

0 голосов
/ 20 декабря 2011

Я думаю, что ответы здесь уже достаточно хорошо отвечают на ваш конкретный вопрос, но, возможно, в более общем плане: если вы пытаетесь отправить данные через объект networkStream для целей сетевого взаимодействия, проверьте библиотеку с открытым исходным кодом, networkComms .net .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...