Это сложно, и зависит от того, как настроен сокет. То, что вы пишете, не соответствует непосредственно полученному:
- сетевой карте может потребоваться разбить ее на пакеты при передаче
- сокет / NIC может быть настроен на объединение пакетов для передачи (сокращение фактических сетевых пакетов, но затрудняет уверенность в том, что вы отправили то, что, как вы думаете, у вас есть - возможно, оно буферизовано локально)
Обратите внимание, в частности, что NetworkStream.Flush()
ничего не делает , поэтому вы не можете использовать это для проталкивания последних нескольких байтов
Хороший компромисс - обернуть NetworkStream
в BufferedStream
и настроить Socket
с NoDelay = true
(отключает локальную буферизацию вывода). BufferedStream
позволяет вам продолжать запись в блоках любого размера (включая отдельные байты), не вызывая огромной фрагментации пакета; BufferedStream
высветится, когда приблизится к заданному размеру. Однако, что важно, теперь у вас есть доступ к BufferedStream
методу Flush()
, который будет очищать буферизованные данные в сети; полезно, если у вас сложный задний разговор и вам нужно знать, что вы отправили конец вашего сообщения.
В противном случае риск состоит в том, что клиент всегда ждет ответа (не осознавая, что у него все еще есть 3 байта, буферизованных локально, поэтому не отправил полный запрос), и сервер не отвечает, потому что он все еще ожидает последние 3 байта запроса. Тупик.