Вопрос по sockets, networking – Как привязать к любому доступному порту?

41

Мне нужно приложение, которое отправляет пакет UDP на некоторый сетевой сервер и получает ответ. Сервер отвечает на тот же номер порта, откуда поступил запрос, поэтому мне сначала нужно привязать () мой сокет к любому номеру порта UDP.

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

Есть ли способ привязать сокет UDP к любому доступному порту? IMO, это должен быть эффективный способ быстро получить свободный номер порта, который используется, например, принять () функцию.

Если нет, то какова лучшая стратегия, чтобы попробовать связывание и проверить статус WSAEADDRINUSE / EADDRINUSE: пробовать порты последовательно, начиная с 1025, или 1025 + rand (), или какой-нибудь другой?

возможно это поможетserverfault.com/questions/447044 yegor256
В POSIX? Также требуется диапазон 1024+:stackoverflow.com/questions/913501/… Ciro Santilli 新疆改造中心 六四事件 法轮功
accept () используется в сокетах на основе соединений, а не в дейтаграммах. Beano

Ваш Ответ

3   ответа
199

bind(), Это позволит вам привязать к определенному IP-адресу (в случае, если у вас естьmultiple установлен) пока еще привязка к случайному порту. Если вам нужно знать, какой порт был выбран, вы можете использоватьgetsockname() после того, как привязка была выполнена.

@EJP Я не оспариваю, что это работает, просто отмечая, что это не задокументированное поведение, кроме (AFAICT) в Windows и Solaris.
Это вbind() документация: & quot; если порт указан как ноль, поставщик услуг назначает приложению уникальный порт из диапазона портов динамического клиента. В Windows Vista и более поздних версиях диапазон динамического клиентского порта - это значение между 49152 и 65535. Это изменение по сравнению с Windows Server 2003 и более ранними версиями, где диапазон динамического клиентского порта - между 1025 и 5000 ... Приложение может использовать getsockname после вызова связать, чтобы узнать адрес и порт, который был назначен сокету. & quot;
@alastair: вопрос помечен какWindows а такжеWinSockВот почему я процитировал документацию Microsoft. AFAIK, привязка к порту 0 задокументирована в стандарте 4.2BSD, на котором основаны реализации платформы.
Привязка к порту 0 является официальным документированным способом привязки к назначенному ОС случайному порту.
В ядре Linux обработка порта # = 0 как запроса случайного назначения считается настолько обыденной, что даже не дается ссылка на спецификации. (net / ipv4 / inet_connection_sock.c, inet_csk_get_port).
0

почему вы не используете сокет udp для отправки данных? Начните с sendto, а затем используйте функцию recvfrom для чтения входящих данных. Кроме того, вы получаете в качестве бонуса адрес, с которого были отправлены данные, прямо здесь, чтобы вы могли отправить ответ обратно.

@ doug65536 это верный пример, но оригинальный вопрос не содержал каких-либо конкретных подробностей того, почему.
Некоторые протоколы требуют, чтобы вы заботились о том, какой номер порта вы используете на своем конце. Например,TFTP клиенты используют его для различения нескольких одновременных передач с одного и того же сервера. Сервер не может просто отправить обратно с одного и того же порта, каждая передача файла требует от сервера отправки с другого исходного порта. Сервер действительно отвечает на адрес источника и порт клиента, как вы обрисовали в общих чертах.
В моем конкретном примере, используя новый сокет для каждой передачи, а затем делать вслепуюsendto будет неявно выбирать исходный порт, но могут быть и другие протоколы, в которых вам все равно, какой будет номер порта, прежде чем вы на самом делеsendto.
35

sendto без звонкаbind во-первых, сокет будет привязан автоматически (к свободному порту).

@ Привет-Ангел: я просто использую голоса и отрицательные голоса, чтобы "сортировать" ответы, когда я спешу, я обычно читаю принятый ответ и ищу разницу в голосовании между первым и вторым ответами (если второй ответ имеет больше голосов, чем принятый, чем его стоит прочитать). Вот как я использую SO, по крайней мере, я не нелогичен сам с собой.
Понижающее голосование только потому, что правильный ответ должен быть @ Remy's (используя порт 0 в bind).
@claf неявное связывание также является связыванием, не так ли? Оба ответа полезны, на мой взгляд.
@ Клаф, по крайней мере, вы объясняете причину. Ты здесь делаешь хорошо. На SO иногда появляются народы, которые просто делают отрицательные голоса, и у них нет ни мозгов, чтобы объяснить причину, ни просто трусов. Или, возможно, оба. Вы хороший человек.
@ Клаф, ты немного нелогичен. Вы отклонили чей-то ответ из-за выбора стартера темы (абсолютно другого человека). Я согласен с тем, что ответ Реми лучше, и он получил заслуженные голоса, но отказался от ответа только потому, что другой лучше - нонсенс. & # X207A; & # xB9; к ответу за несправедливое понижение голосов.

Похожие вопросы