2015-08-03 4 views
1

Я работаю с кодом, который использует XML по протоколу TCP. Эта реализация имеет тайм-аут 10 секунд для каждого send() и recv(), чтобы дождаться целых данных, используя setsockopt(). После некоторого времени работы я обнаружил, что иногда recv() не ждет тайм-аута и возвращает значение -1. Пока я пытался решить проблему, я добавил код sleep(2), и я узнал, что sleep() был прерван каждый раз, когда я столкнулся с ошибкой recv. Исходя из этого, я думаю, что корень проблемы - это сигнал, но я не смог найти, какой сигнал.C++: Может ли setockopt() игнорировать сигнал?

Мой вопрос следующий: Могло ли прерывание recv() прерываться сигналом? Примечание: ожидание recv() «s устанавливается на setsockopt()

EDIT: Вот решение (Спасибо за помощь):

while (buf > 0) 
{ 
    rsize = recv(socket, bufsize, buf, 0) 
    if (rsize == -1) 
    { 
    if (errno == EINTR) 
     continue; 
    break; 
    } 
    break; 
} 
+0

Вы используете Linux? – jxh

+0

Что вы на самом деле имеете в виду _ignored by signal_ ?? Сигналы обрабатываются асинхронно и могут обрабатываться независимо от кода ожидания в разных потоках. –

+0

Ваш _signal aware_ 'recv()' - вопиющий бессмысленный код BTW. –

ответ

0

В Linux (и UNIX в целом), вызов recv() может быть прерывается выдачей сигнала.

[EINTR] recv() функция была прервана сигналом, который был пойман, прежде, чем какие-либо данные были доступны.
POSIX

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

Если вы используете sigaction(), чтобы установить обработчик сигнала, вы можете установить флаг SA_RESTART, чтобы позволить автоматически перезапускать системные вызовы после вызова обработчика сигнала. recv() - один из вызовов, который будет перезагружен под Linux (подробности найдены с man 7 signal).

+0

Есть ли способ обработать этот сигнал, чтобы он не прерывал мой recv()? –

+1

@EdRivera Просто установите флаг 'SA_RESTART' в поле' sa_flags' 'struct sigaction' при настройке обработчика сигнала. Это приведет к автоматическому перезапуску системных вызовов с прерываниями (за некоторыми исключениями). Для получения дополнительной информации см. «Сигнал (7)». –

+0

@ FilipeGonçalves: Ах, спасибо за этот вклад. Поведение SA_RESTART немного отличается от системы, но, по-видимому, это отличный выбор для Linux. – jxh