отправить сокет c ctrl + c поведение - PullRequest
3 голосов
/ 11 мая 2010

Я наблюдаю за приложением, основанным на сервере и различных клиентах, но у меня проблема с командой send. Всякий раз, когда я выполняю ctrl + c на стороне клиента, операция send уничтожает текущий поток и запущенный процесс (для того, чтобы иметь несколько клиентов, для которых я назначил поток) .

Если клиент завершает работу (делает сокет закрытия) правильно, сервер не умирает, но когда я использую комбинацию ctrl + c на клиенте, оба завершаются. *

Что я могу сделать, чтобы команда отправки не имела такого поведения?

Заранее спасибо

Ответы [ 3 ]

3 голосов
/ 11 мая 2010

Проверьте Руководство Beej для сигналов . Вам нужно перехватить и обработать сигнал для CTRL + C , который является SIGINT (сигнал прерывания терминала).

2 голосов
/ 08 июля 2010

Позвольте мне резюмировать, в чем, по моему мнению, ваша проблема: когда вы нажимаете ctrl + c , чтобы закрыть клиент, сервер завершается. И вы хотите, чтобы это поведение обрабатывалось таким образом, чтобы сервер не зависал, как описано выше. Если это правда, пожалуйста, продолжайте читать, я думаю, что смогу пролить некоторый свет на реальную проблему, это не имеет большого отношения к использованию (или не использованию) правильного дескриптора сигнала.

Когда вы закрываете клиент с помощью ctrl + c , ОС остановит клиентский процесс и закроет все открытые им сокеты. В рамках этого FIN будет отправлено на сервер.

Пожалуйста, проверьте ваш код. Я полагаю, что вы написали бы код таким образом, чтобы он блокировался в вызове read () из сокета с соответствующим клиентом. Теперь, когда FIN, отправленный выше, достигает сокета на стороне сервера, это чтение вернется со значением 0.

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

Если приведенный выше сценарий верен, у вас есть 2 выхода: 1. проверьте read (), вернув 0, и продолжайте. 2. установить обработчик сигнала для SIGPIPE.

Я предпочитаю 1-й метод, кстати.

1 голос
/ 11 мая 2010

Чтобы закрыть сокетное соединение и правильно завершить работу клиентской программы на ctrl - c , вам может потребоваться предоставить соответствующий обработчик сигнала для SIGINT. Это выполняется с использованием функций signal() или предпочтительно sigaction().

Этот вопрос и его ответы могут представлять интерес: Как мне закрыть сокет в обработчике сигналов?

В вашей серверной программе вы должны проверять наличие ошибок в каждой функции, связанной с сокетом, например accept() или recv() / read() проверяя возвращаемое значение функции. Если возвращаемое значение из функции указывает на ошибку (обычно -1), посмотрите на errno. Значение errno должно обеспечивать некоторую индикацию относительно характера ошибки и позволяет надлежащим образом обрабатывать случай ошибки. Это должно помочь вам лучше справиться с ситуацией, когда соединение теряется, когда клиентское приложение неожиданно завершает работу.

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