UDP C-сокеты: несколько сокетов совместно используют один порт - PullRequest
1 голос
/ 30 марта 2011

Я пишу программу на C на GNU / Linux, которая использует UDP для обмена сообщениями между различными экземплярами программы, либо на одной машине, либо по сети.Каждый экземпляр программы имеет свой собственный уникальный внутренний адрес уровня приложения, который он использует для различения экземпляров, которые работают на одном компьютере (и, таким образом, совместно используют IP-адрес).В настоящее время вся система взаимодействует через один порт UDP.

Это прекрасно работает между экземплярами программы, работающими на разных компьютерах, поскольку все они имеют уникальные IP-адреса и, следовательно, уникальные сокетные соединения.Проблема заключается в запуске нескольких экземпляров на одном компьютере.В этом случае только первый экземпляр программы получает соединение с сокетом, а остальные не работают, поскольку порт уже используется.

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

  1. Привязать все экземпляры программы на одном компьютере к одному и тому же общему протоколу порта
  2. При получении сообщения каждыйэкземпляр будет использовать recv с установленным флагом MSG_PEEK, чтобы определить, совпадает ли адрес прикладного уровня сообщения с внутренним адресом экземпляра.
  3. Для одного экземпляра на данном компьютере, где адреса совпадают, обычный вызов recv удалитсообщение из входной очереди для обработки соответствующим экземпляром.

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

ЕстьЕсть ли стандартный способ сделать это в GNU C?Я понимаю, что мог бы написать управляющую программу верхнего уровня для прослушивания всех сообщений в сокете и перенаправления их в соответствующий экземпляр, но это кажется излишне сложным и разбивает программу, работающую одинаково с несколькими экземплярами по сети, по сравнению с общим сингломIP.Я также знаю, что могу использовать несколько портов, но это добавляет необходимость назначать каждому экземпляру отдельный свободный порт и отслеживать их по всей сети экземпляров.

По сути, я хочу "передать" сообщение группе экземпляров, использующих один IP-адрес, и позволить им выяснить, кому принадлежит сообщение на прикладном уровне.

Мысли?

Ответы [ 3 ]

1 голос
/ 30 марта 2011

Вы можете сделать такое связывание с setsockopt (SO_REUSEPORT), но я думаю, что это не поможет. У вас будет несколько сокетов, каждый со своей собственной очередью пакетов, и каждый пакет будет идти только в одну очередь. MSG_PEEK не принесёт пользы.

Перенаправление сообщений экземпляра верхнего уровня разным потребителям выглядит как правильное решение.

0 голосов
/ 12 октября 2012

Если это приложение в стиле клиент / сервер, клиентская сторона не должна связываться.

Когда сервер отвечает клиенту, который не привязан, он отвечает на порт источника, который ОС выбирает случайным образом при отправке клиентом (без привязки). Затем клиент читает с несвязанного порта.

0 голосов
/ 30 марта 2011

Нельзя использовать несколько сокетов, привязанных к уникальной комбинации ip / port.

Использовать некоторый интерфейс очереди сообщений / передачи сообщений и забыть о UDP.Например, см. 0MQ (zeromq) http://www.zeromq.org/

...