Изящное завершение работы сокета в Linux - PullRequest
11 голосов
/ 13 марта 2012

Я хочу иметь возможность прекратить прослушивание сокета сервера в linux и убедиться, что все соединения, открытые с точки зрения клиента, правильно обрабатываются и не закрываются внезапно (т. Е. Получают ECONNRESET).

е:

sock = create_socket();
listen(sock, non_zero_backlog);
graceful_close(sock);

если будет достаточно вызова close () и обработки уже принимаемых сокетов accept'd, но могут быть открытые соединения в бэклоге ядра, которые будут внезапно закрыты, если вы вызовете close () на сокете сервера.

Ответы [ 2 ]

6 голосов
/ 13 марта 2012

Единственный рабочий способ сделать это (который я нашел) - это:

  1. не позволяет accept() добавлять больше клиентов

  2. есть где-нибудь список открытых сокетов и ждать, пока они все не закроются должным образом, что означает:

    • с использованием shutdown(), чтобы сообщить клиенту, что вы больше не будете работать с этим сокетом

    • на некоторое время позвоните read(), чтобы убедиться, что все клиенты отправили тем временем было вытащено

    • и затем close() для освобождения каждого клиента сокета.

  3. ТОГДА, вы можете безопасно close() гнездо для прослушивания.

Вы можете (и должны) использовать тайм-аут, чтобы убедиться, что простаивающие соединения не будут длиться вечно.

2 голосов
/ 13 марта 2012

Вы смотрите на ограничение API сокета TCP.Вы можете посмотреть на ECONNRESET как версию сокета EOF, или вы можете реализовать протокол более высокого уровня через TCP, который информирует клиента о надвигающемся отключении.

Однако, если вы попробуете последний вариант,помните о неразрешимой проблеме двух армий , которая делает невозможным постепенное отключение в общем случае;это является частью мотивации для механизма сброса соединения TCP в его нынешнем виде.Даже если бы вы могли написать graceful_close() так, чтобы это работало большую часть времени, вам, вероятно, все равно придется иметь дело с ECONNRESET, если серверный процесс не будет ждать вечно, чтобы получить graceful_close_ack от клиента.

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