Как работает сетевой сокет при записи/чтении?

Добрый день,

Объясните простыми словами, как работает связка сокет-стрим при чтении записи? В частности, мы создаем сокет, создаем стрим, пишем туда данные из буфера, на другом конце в ожидании данных while(true), потом, обычно в примерах, отправили и ждем ответ, в php например $out = socket_read и т.д., а если данных нет или они с задержкой, или сначала там отправили первую часть, а вторая часть через пять секунд отправлена, а здесь уже socket_read == false. Как это все регулируется, чтобы отойти от схемы отправил-сразу получил, закрыл и забыл? Как управлять кто ждет, сколько ждет, чего ждет и т.д.?
  • Вопрос задан
  • 129 просмотров
Решения вопроса 1
AlexanderYudakov
@AlexanderYudakov
C#, 1С, Android, TypeScript
TCP-сокет - это транспортный уровень, его задача: передавать от отправителя получателю последовательность байт, при этом:
а) байты не терять;
б) доставлять эти байты именно в том порядке, в котором они были отправлены.

На этом задачи сокета заканчиваются. Т.е. ваш вопрос не имеет отношения к сокетам.

Вопрос о том, сколько надо читать (и ждать), решается не на транспортном, а на прикладном уровне. Т.е. перед вами фактически стоит задача: разработать протокол прикладного уровня - придумать правила, чего и сколько должна отправлять и ждать каждая из сторон сетевого взаимодействия.

Один из простых способов решения этой задачи - заставить каждую сторону перед отправкой любых данных указывать длину этих данных (например, 4 байта).

Тогда работа получателя в этом случае проста:
1) читаем из сокета 4 байта - длину сообщения;
2) читаем из сокета еще столько байт, сколько указано в длине сообщения.

А на всякие там DataAvailable обращать внимания не стоит, они только вводят в заблуждение. Если нужного нам количества байт еще не поступило - ждем, когда поступит.

Upd.
NetworkStream.DataAvailable всего лишь показывает нам, что данные уже поступили и их можно забрать с помощью Read, однако ничего не говорит о том, сколько еще данных ожидается и уж тем более НЕ сигнализирует о том, что другая сторона закончила передачу данных:

"Use the DataAvailable property to determine if data is ready to be read. If DataAvailable is true, a call to Read returns immediately."
https://docs.microsoft.com/en-us/dotnet/api/system...
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы