Сокеты POSIX: прием соединений с разными транспортными протоколами?

Мне интересно, каковы минимальные требуемые накладные расходы с точки зрения количества прослушивающих портов / серверных сокетов, необходимых для принятия, скажем, N различных соединений, каждое из которых использует другой транспортный протокол, который работает поверх IP, например TCP, SCTP, DCCP, UDP и т. Д.

Конечно, прямолинейный подход заключался бы в наличии N независимых серверных сокетов (каждый из которых создается вызовом socket() с соответствующим параметром protocol), каждый из которых прослушивает уникальный порт. Однако реализация этого подхода в приложении, которое одновременно использует несколько протоколов, была бы чрезвычайно неудобной, поскольку клиенту необходимо было бы знать несколько портов сервера. Кроме того, в одноранговом приложении, которое выполняет одноранговое соединение только один раз для каждого протокола (с одним и тем же клиентом), тот факт, что каждый из N серверных сокетов принимает только одно (клиентское) соединение, выглядит как огромные накладные расходы (N дополнительных сокеты вводятся исключительно для обработки N «реальных» соединений с одним пиринговым клиентом).

Можно ли сделать лучше, например за счет уменьшения количества сокетов слушающего сервера и / или прослушивания одного и того же порта?

(Для простоты можно предположить, что N = 2, одно соединение - TCP, а другое - DCCP или UDP (пожалуйста, не делайте предположений относительно связи без установления соединения, поскольку DCCP ориентирован на соединение).)

РЕДАКТИРОВАТЬ: меня не интересуют N (клиентские) соединения, файловые дескрипторы которых возвращаются N вызовами accept. Вопрос в дополнительных накладных расходах, чтобы сделать эти N соединений возможными (т.е. должен быть хотя бы один дополнительный серверный сокет, который прослушивает входящие соединения).


person eold    schedule 02.12.2013    source источник
comment
Даже представить себе не могу, какой цели могла служить такая конструкция ...   -  person vines    schedule 02.12.2013
comment
«клиенту необходимо знать несколько портов сервера» - почему? Ему нужно знать только тот сервис, который он хочет использовать.   -  person Martin James    schedule 02.12.2013
comment
Если вы хотите транслировать огромный объем данных в приложении LAN, например, использование такого протокола, как UDP, имеет смысл, если вас не волнуют потеря пакетов и их переупорядочение.   -  person eold    schedule 02.12.2013
comment
Зачем каждому серверу нужно N сокетов на клиента? Сервер просто запустит N серверный сокет и создаст дополнительные сокеты по мере подключения клиентов. В любом случае API сокетов требует, чтобы вы создавали по крайней мере 1 сокет для каждого типа транспорта, вы не можете объединить несколько транспортов в один сокет.   -  person nos    schedule 02.12.2013
comment
@MartinJames: Предположим, клиент хочет установить TCP-соединение с одним и тем же сервером, а также соединение DCCP / UDP / STCP с той же службой. Конечно, одним из подходов было бы установить первое и позволить серверу отправлять номер порта для другого соединения через первое соединение. Но можете ли вы сделать лучше, чем это?   -  person eold    schedule 02.12.2013
comment
@nos: Здесь я говорю о серверных сокетах, которые на самом деле слушают. Конечно, клиентские соединения создаются только с помощью вызова accept, который возвращает файловый дескриптор во вновь созданный клиентский сокет.   -  person eold    schedule 02.12.2013
comment
@leden Тогда я не понимаю, о чем вы действительно спрашиваете. Если вы хотите, чтобы клиенты подключались к N различным произвольным транспортам, клиент создает столько сокетов, сколько он хочет подключиться. Сервер прослушивает N сокетов с четко определенными номерами портов. (Или вы можете, как вы говорите, иметь только один четко определенный протокол / порт, например TCP, и создавать другие по запросу, отправляя номер порта обратно)   -  person nos    schedule 02.12.2013
comment
@nos: можем ли мы каким-то образом избежать открытия этих N прослушивающих сокетов или, по крайней мере, заставить их прослушивать один и тот же порт и каким-то образом различать в зависимости от протокола? Вот в чем суть - как управлять теми, у кого меньше накладных расходов ...   -  person eold    schedule 02.12.2013
comment
@leden Хорошо. Ответ - нет. В API сокетов нет такой концепции.   -  person nos    schedule 02.12.2013
comment
@leden, почему вы думаете, что совместное использование обработчика сокета при разделении всего остального снизит накладные расходы? ..   -  person vines    schedule 02.12.2013


Ответы (1)


Подводя итог сказанному в комментариях выше: Поскольку в

int socket(int domain, int type, int protocol)

call мы должны указать protocol, мы не можем использовать один сокет для нескольких протоколов. Мы также не можем переносить запись

socket(AF_INET, SOCK_RAW, 0);

см. SOCK_RAW Demystified.

Что касается использования одного и того же порта с разными сокетами: возможность этого зависит от системы; е. г. см. HP-UX (man 7f inet):

  The local port address is selected from independent domains for TCP
  and UDP sockets.  This means that creating a TCP socket and binding it
  to local port number 10000, for example, does not interfere with
  creating a UDP socket and also binding it to local port number 10000
  at the same time.

по сравнению с Linux (man ip):

  Only one IP socket may be bound to any given local (address, port) pair.
person Armali    schedule 05.11.2014