проблема send () - PullRequest
       18

проблема send ()

2 голосов
/ 13 апреля 2011

Когда я тестирую свою программу с помощью веб-браузера, я могу нормально писать в сокет / FD, поэтому я решил зациклить его и обрезать соединение, и я заметил проблему.send () может закрыть всю программу, когда сокет недоступен.Я думал, что проблема была в том, что программа поймала себя на catch-22 и закрылась.Поэтому я установил сокет не блокировать.Без изменений.Есть идеи, почему это происходит?

else if ( b->temp_socket_list[read].revents & POLLOUT ) {  
    printf ( "#Write#\n" );  
    char *done = "Done!";  
    int sent = send ( sock, done, 5, 0 );  
    printf ( "end\n", sent );  
}  

Ответы [ 4 ]

5 голосов
/ 13 апреля 2011

Вероятно, это связано с действием по умолчанию сигнала SIGPIPE.Чтобы игнорировать этот сигнал, используйте что-то вроде:

signal(SIGPIPE, SIG_IGN);

Ошибки сокета будут затем сообщаться как возвращаемые значения из функций сокета, а не как сигнал.

3 голосов
/ 13 апреля 2011

Какая это платформа?

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

3 голосов
/ 13 апреля 2011

В качестве альтернативы игнорированию SIGPIPE, этот пост содержит несколько хороших ответов о том, как их избежать.

0 голосов
/ 13 апреля 2011

Попробуйте это:

sigset_t set, oldset;
sigemptyset(&set);
sigaddset(&set, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &set, &oldset);
/* use send all you like here */
sigtimedwait(&set, 0, (struct timespec [1]){0});
pthread_sigmask(SIG_SETMASK, &oldset, 0);

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

Также обратите внимание, что если программа (или даже просто текущий поток) не хочет использовать SIGPIPE, вы можете значительно упростить этопросто оставив SIGPIPE навсегда заблокированным:

sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &set, &oldset);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...