2009-04-01 3 views
8

Ситуация: Сервер вызывает accept(). Клиент отправляет SYN серверу. Сервер получает SYN, а затем отправляет SYN/ACK обратно клиенту. Тем не менее, клиент теперь зависает/умирает, поэтому он никогда не отправляет ACK обратно на сервер.Сокеты TCP и POSIX accept() семантика

Что происходит? Возвращает ли accept() сразу после получения SYN или блокируется до тех пор, пока не будет возвращен ACK клиента? Если он блокируется, значит ли это в конечном итоге тайм-аут?

ответ

9

Звонок в accept() блокируется до его соединения. Если до тех пор, пока не будет завершено 3-стороннее рукопожатие, не подключено, поэтому accept() не должен возвращаться. Для неблокирующих сокетов он не будет блокироваться, но он также не даст вам информацию о частично выполненных рукопожатиях.

1

В конечном итоге это закончится, потому что этот сценарий фактически является DoS (отказ в обслуживании) и ресурсом для accept, возвращаемого для использования операционной системой. если это может привести к блокировке главного сокета, так как клиент подключается к серверу после того, как он возвращает с действительным файловым дескриптором.

В случае возникновения ошибки во время соединения с клиентом будет установлено значение errno и хорошей идеей будет журнал или отображение сообщения об ошибке. , однако читайте страницы man, это самый лучший источник информации в большинстве случаев.

2

Если клиент никогда не отправляет ACK, accept() будет либо блокировать, либо возвращать EAGAIN, если сокет отмечен как неблокирующий.

0

В случае сбоя, скажем, тайм-аут, потому что рукопожатие не завершено, оно вернет -1 и установит errno. Я верю, посмотрев на страницу руководства, что он установит errno в ECONNABORTED.

Смежные вопросы