Связывание несколько раз с одним и тем же портом - PullRequest
1 голос
/ 12 сентября 2010

есть ли способ связать несколько прослушивающих сокетов TCP на одном и том же {IP, порт}? Я знаю, что могу просто открыть сокет, связать, разветвить и затем слушать в каждом из процессов. Но я хотел бы сделать то же самое с отдельными процессами, которые не могут разветвляться после привязки. Есть ли способ разрешить это и не получить сообщение об ошибке «Адрес уже используется»?

Единственная опция, которая мне нужна, - автоматическая балансировка нагрузки соединений.

Ответы [ 6 ]

4 голосов
/ 12 сентября 2010

Похоже, имеет смысл ввести отдельный процесс, который будет прослушивать порт и действовать как прокси-сервер с балансировкой нагрузки, перенаправляющий трафик в пул внутренних процессов, либо через интерфейс обратной связи, либо через сокеты Unix.Если вы имеете дело с HTTP, вы можете использовать один из существующих обратных прокси-серверов HTTP, например pound или nginx .

3 голосов
/ 12 сентября 2010

Вы можете сделать что-то подобное и пропустить сокет fd через сокет домена unix, как предложено здесь

2 голосов
/ 12 сентября 2010

К сожалению, я не верю, что это возможно.

1 голос
/ 06 декабря 2016

представляется "новым возможным" для Linux с ядром 3.9 http://freeprogrammersblog.vhex.net/post/linux-39-introdued-new-way-of-writing-socket-servers/2

с использованием SO_REUSEPORT

1 голос
/ 12 сентября 2010

Только один процесс может привязать сокет TCP к данному порту и IP-адресу (даже если это INADDR_ANY) - это будет полностью дублирующее связывание .Единственное исключение из этого - танец bind(2) / fork(2), как вы уже упоминали.

При этом, если у вас есть несколько сетевых интерфейсов на машине (или настройте псевдонимы IP на одном интерфейсе),Вы можете привязать один сокет к каждому IP-адресу с тем же портом.Просто не забудьте установить опцию сокета SO_REUSEADDR между socket(2) и bind(2) вызовами.

Балансировка нагрузки может быть выполнена несколькими способами:

  • сделать это на источнике сопоставления брандмауэраIP-адреса к пулу машин / портов,
  • прокси / предварительный процесс в одном процессе, реальная работа в пуле процессов,
  • использование файлового дескриптора, передавая как @Хастуркун предлагает.
0 голосов
/ 13 сентября 2010

Для очень опытного варианта вашей задачи в Linux вы можете отобразить входящие пакеты в ваш процесс, используя модуль очереди netfilter.Затем вы можете удалить / изменить / их.

prog1: checks if packet came from IP xxx.xxx.xxx. Match? Catch packet.
prog2: checks if prog3 busy. Match? Catch packet.
prog3: checks packet's origin...

Однако это приводит к ~ 20 КБ кода только для обработки пакетов, и ваш стек TCP / IP не выдержит его долго (большой трафик == большая ошибка).

В Windows вы можете добиться того же с помощью драйвера Winsock.

Это эзотерическое решение, просто создайте один диспетчерский процесс, чтобы раскошелиться на другие.Позаботьтесь о nginx, apache2, cometd или любом асинхронном TCP-модуле Perl, чтобы уловить идею.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...