Блокирует ли connect () сокет TCP? - PullRequest
12 голосов
/ 24 ноября 2011

Привет, я читаю TLPI (Интерфейс программирования Linux), у меня есть вопрос о connect ().

Как я понимаю, connect () немедленно вернется, если ожидающие номера соединения listen () нене доходят до «отставания».И это будет блокировать в противном случае.(согласно рисунку 56-2)

Но для сокета TCP он всегда будет блокироваться, пока не будет вызван метод accept () на стороне сервера (согласно рисунку 61-5).

Правильно ли я?Поскольку я видел это в примере кода (p.1265), он вызывает listen () для прослушивания определенного порта, а затем вызывает connect () к этому порту, ДО того, как вызвать accept ().

So connect ()блоки навсегда в этом случае, не так ли?

Спасибо !!

Ответы [ 3 ]

23 голосов
/ 24 ноября 2011

Вряд ли что-либо "немедленно" касательно сети, вещи могут быть потеряны в пути, и операция, которая должна быть выполнена немедленно в теории, может не сделать этого на практике, и в любом случае есть время окончания передачи.

Тем не менее

  • connect () на сокете TCP является блокирующей операцией, если дескриптор сокета не переведен в неблокирующий режим.

  • ОС заботится о квитировании TCP, когда квитирование завершено, connect () возвращается. (то есть, connect () не блокируется, пока другие конечные вызовы accept ())

  • Успешное TCP-квитирование будет поставлено в очередь серверному приложению и может быть принято accept () в любое время позже.

3 голосов
/ 24 ноября 2011

connect () блокирует до завершения трехстороннего рукопожатия TCP.Рукопожатие на стороне прослушивания обрабатывается стеком TCP / IP в ядре и завершается без уведомления пользовательского процесса.Только после того, как рукопожатие завершено (и инициатор уже может вернуться из вызова connect ()), accept () в пользовательском процессе может подобрать новый сокет и вернуться.Для завершения рукопожатия не требуется ожидание accept ().

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

3 голосов
/ 24 ноября 2011

connect является блокирующим вызовом по умолчанию, но вы можете сделать его неблокирующим, передав socket флаг SOCK_NONBLOCK.

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