Я думаю, что проблемы (неудовлетворительное поведение, которое вы не описываете) происходят из другого источника. Позвольте мне перечислить некоторые идеи и комментарии c. / Что было сказано ранее:
(1) блоки recvfrom () тоже. Тем не менее, вы хотите использовать его. Ваше сообщение в настоящее время отправляет и получает от обратной связи, что хорошо для вашей игрушечной программы (но: см. Ниже). При получении данных UDP с помощью recv () вы не знаете, кто их отправил, поскольку сокет никогда не был подключен (). Используйте recvfrom (), чтобы подготовиться к минимальной проверке ошибок в более серьезной программе
(2), так как select () приостанавливает работу программы до ввода / вывода, это только поставит любую проблему с блокировкой сокета на другой уровень. Но это не проблема
(3), чтобы проверить, пуст ли приемный буфер, используйте флаг MSG_PEEK в recvfrom () в соответствующей позиции. Обычно он используется только для работы с дефицитом памяти, но он должен выполнять свою работу.
(4) причина 1, почему я считаю, что вы видите проблемы, которые вы не описали более подробно:
UDP-дейтаграммы сохраняют границы сообщений. Это означает, что recvfrom () будет считывать весь кусок данных, составляющих любое отправленное сообщение. Однако, если буфер, в который вы его читаете, меньше, чем считанные данные, любой излишек будет отброшен. Поэтому убедитесь, что у вас большой буфер (в идеале 65 тыс.).
(5) причина 2:
Вы получаете любые данные, отправленные в петлю. Если вы в настоящее время также подключены к какой-либо сети (спутниковая сеть, Интернет), то, что вы ловите, может быть из другого источника, чем вы ожидаете. Поэтому, по крайней мере, в фазе покоя, отключите.
Блокировка не должна быть проблемой. Ваша основная логика, когда она написана правильно:
Recvfrom () (блокировка / ожидание до готовности)
Процесс
Peek, если буфер пуст
Выход если да
Вернитесь назад, чтобы получить больше, если нет,
и вы, кажется, хотите сделать это в настоящее время. Поскольку вы не используете многопоточность, не оптимизируете производительность и т. П., Вам не следует беспокоиться о блокировке. Если ваш приемный буфер слишком мал, увеличьте его размер, используя
Setsockopt () для optName SO_RCVBUF