2010-03-04 8 views
7

Я довольно новичок в программировании и программировании сети esp, поэтому, если это глупо, не вздумайте слишком сильно, пожалуйста, спасибо.UDP и сокеты, recvfrom() return -1 и ресурс временно недоступен

У меня есть клиент и сервер, которые взаимодействуют с диаграммами (UDP) в C. client отправляет 5 msgs и после получения сообщений сервер отправляет сообщения обратно. прием и отправка сообщений велик, пока клиент не завершит получение сообщений. после того, как сервер отправит все сообщения обратно, он завершает работу с помощью функции close(). поэтому recvfrom() от клиента должен вернуть 0, правильно?

Предполагая, что recvfrom() должен возвращать 0 при закрытии() со стороны сервера, он возвращает -1 вместо этого, при ошибке Ресурс временно недоступен. это ссылка на ресурс для закрытого сокета с сервера? или это для чего-то другого, совсем другого, как бег из буфера или что-то (что я не думаю, что это правда)?

и предполагая, мое предположение было неправильным и -1 возвращается, потому что сервер завершается, я, вероятно, должен обработать ошибку с

if(SOMEMACRO) 
    do something 

но как я выяснить, что SOMEMACRO есть? Я распечатываю ошибку, но он говорит, что ресурс temp недоступен и recvfrom() описание не упоминает о непригодном ресурсе ..?

btw Это не блокирующий сокет, если это имеет какое-либо значение, поскольку я читал, что если O_NONBLOCK установлен и никакие msgs не доступны, это установит errno в EAGAIN или EWOULDBLOCK. O_NONBLOCK не установлен, но установлен MSG_DONTWAIT. это в основном то же самое, что и O_NONBLOCK для общих файловых дескрипторов, а MSG_DONTWAIT - сокет специфический ??

Мой мозг сейчас не работает так хорошо, если кто-то может просветить меня и выяснить, что такое мое замешательство, я бы очень признателен. Благодаря!

ответ

13

UDP является протоколом без, в отличие от TCP, который ориентированный на соединение. Ваш код получения не будет знать, закрыл ли его сокет или нет, он знает только, есть ли данные, ожидающие чтения. Согласно странице человека для recvfrom на Linux:

Если сообщения не доступны в сокет, получать звонки ждать сообщение, чтобы прибыть, если сокет не неблокируемый (см Fcntl (2)), в этом случае возвращается значение -1, а внешняя переменная errno устанавливается в EAGAIN.

Это, кажется, что происходит для вас

Edit: Обратите внимание, что «ресурс временно недоступен» и EAGAIN одни и те же ошибки, один только пользователь дружественный descption против имени определения.В основном это просто говорит вам, что вы пытаетесь читать из сокета, и нет данных для чтения

+1

Итак, если вы используете UDP, возвращаете ли возвращенное значение() когда-либо? так как вы никогда не знаете, выполнил ли сверстник упорядоченное закрытие? –

+2

@Fantastic Fourier - UDP может фактически отправить дейтаграмму, которая является только заголовками IP и UDP, но не содержит данных. Это совершенно легально и будет выглядеть как чтение из 0 байтов. – Duck

+0

@ Фантастический Фурье - Строго говоря, поскольку в UDP нет «соединения», ничего не нужно закрывать, упорядочивать или иначе. – Duck

2

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

Вот несколько ссылок для вас.

http://msdn.microsoft.com/en-us/library/ms740476%28VS.85%29.aspx http://docs.hp.com/en/B2355-90136/ch03s01.html

А вот пример, прокрутите вниз до udp_listen функции:

http://www.codase.com/search/display?file=L2dlbnRvbzIvdmFyL3RtcC9yZXBvcy9jb2Rhc2UuYy9zbGlycC0xLjAuMTYvd29yay9zbGlycC0xLjAuMTYvc3JjL3VkcC5j&lang=c&off=15730+15796+

Смежные вопросы