Чтение нескольких UDP-сообщений без опроса
Я хотел бы использовать recvmmsg
вызов для чтения нескольких UDP-сообщений из одного гнезда одновременно. Я читаю данные из одной многоадресной группы.
Когда я читаю данные TCP, я обычно использую poll/select
с неблокирующим сокетом (и тайм-аутом), который будет уведомлен, когда он будет готов для чтения. Я придерживаюсь этого подхода, поскольку я знаю о проблеме ложного пробуждения и потенциальных проблем, связанных с наличием блокирующего сокета.
Поскольку мое заявление должно быть очень быстрым, если я буду следовать тому же подходу с recvmmsg
Я введу дополнительный системный вызов (poll/select
) это может замедлить выполнение.
Итак, два моих вопроса следующие:
- С UDP, я могу безопасно читать из сокетов BLOCKING, используя
recvmmsg
безpoll/select
или я должен применять тот же принцип, который я использовал для TCP (неблокирование + опрос)? - Предположим, у меня огромное количество многоадресного трафика, вы бы выбрали неблокирующий сокет +
recvmmsg
только (без опроса) и много ли горят процессоры?
Я использую Linux: CentOS 7 и Oracle Linux.
2 ответа
Вы всегда можете использовать режим блокировки с сокетами TCP и UDP.
Если вы хотите наложить тайм-аут чтения, есть setsockopt()
с SO_RCVTIMEO
вариант.
Я придерживаюсь этого подхода, поскольку я знаю о проблеме ложного пробуждения
Какой ложный пробуждение? Никогда не видел этого за 25 лет сетевого программирования.
и потенциальные проблемы с наличием блокирующего разъема.
Никогда о них не слышал.
С помощью select()
и неблокирующий режим с одним сокетом не имеет смысла, если ваша платформа не поддерживает SO_RCVTIMEO
, Для начала это дополнительный системный вызов.
Возможность использования блокировки или неблокирования зависит от конечной цели приложения. - Скажем, это просто пример приложения чата, показывающий использование UDP в сочетании с TCP, тогда вы можете использовать любой из них. - Но если вы планируете сделать этот модуль частью широко используемого приложения с большим объемом передаваемых данных, то, вероятно, пригодится создание нескольких потоков / процессов для решения различных задач. Родительский поток будет ожидать сообщения, но для обработки он создаст другой дочерний поток и, следовательно, сделает родителя доступным для следующего сообщения.
Но в двух словах я не вижу никаких проблем с вашим первым вариантом использования блокирующего сокета без poll/select
для приложения UDP, учитывая, что это просто для домашней работы.