Как закрыть неблокирующую розетку? - PullRequest
6 голосов
/ 21 июня 2011

Я полагаю, что если мы вызываем системный вызов close на неблокирующем сокете, он немедленно возвращается, тогда как обработать ответ? закрыто ли это или нет? другими словами, каково поведение системного вызова close для неблокирующего сокета?

Ответы [ 2 ]

6 голосов
/ 21 июня 2011

Важно не состояние блокировки сокета, а опция SO_LINGERgetsockopt(2):

SO_LINGER управляет действием, выполняемым, когда неотправленные сообщения помещаются в очередь на сокете и выполняется close(2).Если сокет обещает надежную доставку данных и установлен SO_LINGER, система будет блокировать процесс при попытке close(2) до тех пор, пока не сможет передать данные или пока не решит, что не может доставить информацию (период ожидания, называемый интервалом задержки, задается в секундах в системном вызове setsockopt(), когда запрашивается SO_LINGER).Если SO_LINGER отключен и выдается close(2), система будет обрабатывать закрытие таким образом, чтобы процесс мог продолжаться максимально быстро.

То есть с SO_LINGERВключение ошибки от close(2) на сокете TCP означало бы, что ядро ​​не могло доставить данные в течение интервала задержки (не считая других ошибок, таких как неверный дескриптор файла и т. д.).С затянувшимся инвалидом - никогда не знаешь.Также см. Последняя страница SO_LINGER, или почему мой tcp ненадежен .

2 голосов
/ 21 июня 2011

если мы вызываем системный вызов close на неблокирующий сокет возвращает немедленно

Гнездо всегда закрыто: соединение может все еще выполнять запись в одноранговый узел. Но ваш вопрос заключает в себе ошибку: если вы вызываете close () для любого сокета, он немедленно возвращается. Закрытие и запись в сокет происходит асинхронно. Вы можете контролировать это с помощью SO_LINGER согласно другому ответу, хотя я подозреваю, что это применимо только к режиму блокировки. Возможно, вам следует перевести сокет обратно в режим блокировки, прежде чем закрывать его с положительным SO_LINGER, если это то, что вам нужно сделать.

...