LINUX.ORG.RU

Вопрос про recvfrom

 


0

1

Здравствуйте.

Скажите, как правильно обрабатывать ошибку recvfrom?

То есть, вот кусок udp-сервера, который в цикле принимает соединения...

while(1) 
     {  
        int n;
        if((n = recvfrom(sd, read_buffer, BREADSIZE - 1, 0, NULL, NULL)) < 0)
         {
           close(sd);
           exit(0);
         }

...если возникла ошибка, то нужно закрывать сокет и гасить прогу или можно сделать так...

while(1) 
     {  
        int n;
        if((n = recvfrom(sd, read_buffer, BREADSIZE - 1, 0, NULL, NULL)) < 0)
         {
           printf("error socket\n");
           continue;
         }

Сильно не пинайте ибо не понятно, какие последствия грядут?

То есть ясно, что ошибка EBADF (неверный дескриптор) погубит меня, но вот например ECONNREFUSED (сетевой компьютер с другой стороны отказался устанавливать сетевое соединение (обычно потому, что там не работает запрошенный сервис)), к чему приведёт?

Спасибо.

(язык си, линукс).


То есть ясно, что ошибка EBADF (неверный дескриптор) погубит меня, но вот например ECONNREFUSED (сетевой компьютер с другой стороны отказался устанавливать сетевое соединение (обычно потому, что там не работает запрошенный сервис))

Сам спросил — сам ответил. :-)

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

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

Сам спросил — сам ответил. :-)

Спасибо.

Получается, что нужно прописывать все ошибки... Это поэтому во всяческих примерах просто закрывают программу?

stD
() автор топика
Ответ на: комментарий от stD

Получается, что нужно прописывать все ошибки...

В реальной программе — да.

Это поэтому во всяческих примерах просто закрывают программу?

В демо-примере можно для простоты и так.

aureliano15 ★★
()

От сервера ожидается устойчивая работа под нагрузкой, то есть подразумевается что если он сумел запуститься и прибиндиться на нужный порт, то выключится он только когда его остановит администратор. Berkeley sockets это блокирующий API (по умолчанию), соответственно надо обрабатывать EINTR. Сервер могут ддосить, поэтому надо обрабатывать ENOMEM. ECONNREFUSED может вернуться от предыдущих send() через этот сокет, поэтому тоже надо обрабатывать.

d_a ★★★★★
()
Ответ на: комментарий от d_a

Сервер могут ддосить, поэтому надо обрабатывать ENOMEM

Лучше просто схлопнуться по ENOMEM в лупе, чем пытаться ловить волшебство ниже по стеку. Мониторинг процессов никто не отменял и проще, со всех сторон, быстро сложить лапки, чем корежить память.

anonymous
()

лучше скачать любую книжку по сетевому программированию, найти примеры на гитхабе, и постигнуть дзен в саморазвитии чем бегать на форум спрашивать что да как

anonymous
()

ECONNREFUSED (сетевой компьютер с другой стороны

если это кусок udp-сервера то такого быть просто не может.

MKuznetsov ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.