Linux - тайм-аут при отключенной отправке

Я занимаюсь разработкой серверного приложения, и у меня возникла следующая проблема с отправкой данных клиенту, которая внезапно разрывает соединение.

Когда я звоню send на сокете блокировки с тайм-аутом записи, установленным через setsockopt(SO_SNDTIMEO) и клиент отключается во время отправки (т. е. отправляется несколько байтов, затем клиент правильно завершает TCP - как видно из wireshark), send все еще блокирует, пока не истечет время ожидания отправки. Следующий звонок send возвращает ошибку, как и ожидалось.

Я ожидаю, что завершение TCP (FIN/ACK) приведет к блокировке send чтобы вернуться немедленно, а не после истечения времени ожидания.

Кто-нибудь когда-нибудь видел такое поведение? Это нормально?

1 ответ

Решение

Нет, FIN, отправленный с клиента, не разблокирует send() на сервере. Когда клиент звонит close() FIN отправляется на сервер, и соединение закрывается для направления от клиента к серверу. Направление от сервера к клиенту все еще открыто до вызова сервера close() и FIN отправляется клиенту.

Когда клиент отправляет FIN, а сервер отправляет ACK обратно, соединение на сервере находится в состоянии CLOSE_WAIT, а соединение на клиенте - в состоянии FIN_WAIT_2. Сервер по-прежнему может отправлять данные, а клиент по-прежнему может получать данные, пока сервер не закроет соединение.

Закрытое соединение не может быть обнаружено через send(), Только recv() обнаруживает соединение, закрытое узлом

Если ваш код должен выполнить немедленное действие, когда клиент закрывает соединение, он должен вызвать poll() или же select() и использовать неблокирующие send() а также recv() звонки.

Другие вопросы по тегам