POSIX-сокеты: принимать соединения с различными транспортными протоколами?
Мне интересно, каковы минимальные требуемые издержки с точки зрения количества прослушивающих портов / серверных сокетов, требуемых для принятия, скажем, N различных соединений, каждое из которых использует свой собственный транспортный протокол, который работает поверх IP, например, TCP, SCTP, DCCP, UDP и т.п.
Конечно, простой подход состоит в том, чтобы иметь N независимых сокетов сервера (каждый из которых создается с помощью вызова socket()
с соответствующими protocol
параметр), каждое прослушивание на уникальный порт. Однако реализация этого подхода в приложении, которое использует несколько протоколов одновременно, будет крайне неудобной, поскольку клиенту необходимо знать несколько портов сервера. Кроме того, в одноранговом приложении, которое выполняет пиринг только один раз для каждого протокола (с одним и тем же клиентом), тот факт, что каждый из N сокетов сервера принимает только одно (клиентское) соединение, выглядит как огромные издержки (N дополнительных сокеты вводятся исключительно для обработки N "настоящих" подключений к одному пиринговому клиенту).
Можно ли сделать это лучше, например, сократив количество сокетов прослушивающего сервера и / или прослушивая один и тот же порт?
(Для простоты вы можете предположить, что N=2, одно соединение - TCP, а другое - DCCP или UDP (не делайте предположений относительно связи без установления соединения, поскольку DCCP ориентирован на соединение).)
РЕДАКТИРОВАТЬ: Меня не интересуют N (клиентские) соединения, файловые дескрипторы которых возвращаются N вызовами accept
, Речь идет о дополнительных издержках, чтобы сделать эти N соединений возможными (то есть должен быть хотя бы один дополнительный серверный сокет, который прослушивает входящие соединения).
1 ответ
Подводя итог тому, что сказано в комментариях выше: Так как в
int socket(int domain, int type, int protocol)
позвонить мы должны указать protocol
Мы не можем использовать один сокет для нескольких протоколов. Мы также не можем писать портативно
socket(AF_INET, SOCK_RAW, 0);
см. SOCK_RAW Демистифицировано.
Что касается использования одного и того же порта с разными сокетами: вероятность этого зависит от системы; например, см. 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.