Природа потоков, построенных поверх сокетов, заключается в том, что у вас есть открытый конвейер, который передает и получает данные до тех пор, пока сокет не будет закрыт.
Однако из-за характера взаимодействия клиент-сервер этот конвейер не всегда имеет контент для чтения. Клиент и сервер должны согласиться отправлять контент по конвейеру.
Когда вы берете абстракцию Stream
в .NET и накладываете ее на концепцию сокетов, все еще действует требование соглашения между клиентом и сервером; вы можете звонить Stream.Read
сколько хотите, но если сокет, к которому ваш Stream
подключен с другой стороны, не отправляет контент, вызов будет просто ждать, пока контент не будет.
Вот почему существуют протоколы. На самом базовом уровне они помогают определить, что такое полное сообщение, которое отправляется между двумя сторонами. Обычно этот механизм является чем-то вроде:
- Сообщение с префиксом длины, в котором отправляется число считываемых байтов до сообщения
- Шаблон символов, используемых для обозначения конца сообщения (это менее распространено в зависимости от отправляемого содержимого, чем более произвольной может быть любая часть сообщения, тем менее вероятно, что это будет использовано)
Это сказало, что вы не придерживаетесь вышеупомянутого; ваш вызов Stream.Read
просто говорит «прочитать 1024 байта», хотя в действительности не может быть прочитано 1024 байта. Если это так, вызов Stream.Read
будет блокироваться, пока он не будет заполнен.
Причина, по которой вызов Thread.Sleep
, вероятно, работает, заключается в том, что к тому времени, как проходит секунда, Stream
имеет 1024 байта для чтения и не блокируется.
Кроме того, если вы действительно хотите прочитать 1024 байта, вы не можете предполагать, что вызов Stream.Read
заполнит 1024 байта данных. Возвращаемое значение для метода Stream.Read
сообщает вам, сколько байтов действительно было прочитано. Если вам нужно больше для вашего сообщения, то вам нужно сделать дополнительные звонки на Stream.Read
.
Джон Скит написал точный способ сделать это , если вы хотите образец.