Сокеты: клиенты выходят без возврата, когда сервер выключается - PullRequest
0 голосов
/ 13 июня 2011

Я создаю простой поток TCP / клиент-сервер, и моя проблема в том, что когда я убиваю серверное приложение, клиентское приложение просто грациозно завершается.Нет вывода в STDERR, и recv () не возвращает 0 или -1, клиентское приложение просто останавливается.

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

Любая помощь в этом вопросе очень ценится!

Ответы [ 2 ]

0 голосов
/ 15 июня 2011

Когда вы убиваете свое клиентское приложение, операционная система закрывает все свои открытые дескрипторы ввода-вывода. Когда TCP-соединение закрывается таким образом, оно отправляет FIN своему партнеру. В этом отношении, убить вашего клиента неотличимо от того, чтобы он грациозно вышел из него.

После установления TCP-соединения понятия «клиент» и «сервер» отсутствуют; это простой, двунаправленный канал связи. Результат, с точки зрения сети / сокетов, один и тот же, независимо от того, какая сторона прервана.

Если вы видите различия в поведении, то это в программировании двух приложений. Блокирующий вызов recv() должен возвращать количество байтов, которые были доступны при закрытии соединения, или, возможно, -1 при ошибке.

Я предлагаю использовать strace <client program and args> в вашем процессе, чтобы точно узнать, что происходит с этим системным вызовом.

0 голосов
/ 14 июня 2011

Это, вероятно, связано с повышением SIGPIPE, которое произойдет при попытке записи в соединение, которое было закрыто другим концом. По умолчанию SIGPIPE в итоге завершит процесс, чтобы предотвратить потерю множества системных ресурсов, генерирующих выходные данные, которые никуда не денутся. Чтобы предотвратить это, вы можете игнорировать сигнал:

signal(SIGPIPE, SIG_IGN);

Если вы сделаете это, вызов send должен работать как положено.

...