То, какое значение будет recv () возврат, если это получит допустимый пакет TCP с полезной нагрузкой, измерило 0

В программировании сокета TCP, если recv() возвраты 0, это взято в качестве признака, что другая сторона закрыла свое соединение. Однако AFAIK, RFC TCP не передает под мандат полезную нагрузку TCP, чтобы быть> 0. Так, теоретически, стек TCP может получить сообщение с полезной нагрузкой 0.

Так, по существу мой вопрос - то, что будет recv() возвраты, если это получает пакет полезной нагрузки, измерили 0? Если это возвращается 0, то, как мы отличаем его от закрытого признака соединения.

5
задан Aditya Sehgal 7 July 2010 в 19:16
поделиться

2 ответа

Сегменты TCP с размером полезной нагрузки 0 вездесущи - они встречаются практически в каждом реальном потоке TCP. Они посылаются всякий раз, когда одна сторона хочет подтвердить получение данных от другой, но не имеет собственных данных для отправки. (Такие пакеты обычно называют "пакетами ACK", но "пакет ACK" - это обычный сегмент, не содержащий данных).

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

Помните, что TCP ориентирован на поток: существует не соответствие 1 к 1 между данными, возвращаемыми одним вызовом recv(), и данными в одном сегменте TCP. Один вызов recv() может вернуть блок данных, перекрывающий несколько сегментов TCP, а данные одного сегмента TCP могут быть возвращены несколькими вызовами recv(). Границы между сегментами TCP не видны приложению, использующему BSD sockets API. Если вам нужны такие границы, вам нужно либо реализовать их самостоятельно, используя протокол прикладного уровня внутри TCP-потока, либо использовать протокол, ориентированный на дейтаграммы, например UDP.

11
ответ дан 18 December 2019 в 13:10
поделиться

Правильно, согласно POSIX, если recv возвращает 0, то соединение корректно закрыто peer'ом.

Если кому-то удалось отправить TCP-пакет с полезной нагрузкой нулевого размера, то ОС не должна возвращать никаких данных процессу, блокируемому на системном вызове recv на этом сокете.

Помните, что полезная нагрузка TCP образует непрерывный поток, который может быть произвольно нарезан ОС, а не последовательность дейтаграмм, которые должны быть возвращены во время одного системного вызова.

3
ответ дан 18 December 2019 в 13:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: