Можно ли подключиться к TCP-порту 0?

59

Прослушивание TCP-порта 0 выделяет мне свободный номер порта в системе.

Но что происходит, когда я пытаюсь подключиться к TCP-порту 0? Очевидный ответ: «Это не работает»:

$ nc localhost 0                 
nc: port number too small: 0

Где в системе это обрабатывается? В стеке TCP ядра ОС? Есть ли Unix, где будет работать подключение к TCP-порту 0?

NH2
источник
2
Теоретически вы могли бы создать собственный стек TCP, в котором работает прослушивание или подключение через порт 0, что означает, что две такие реализации могут общаться друг с другом через порт 0.
Джошуа

Ответы:

60

Просто чтобы убедиться, что мы находимся на одной странице (ваш вопрос неоднозначен), запрос на привязку TCP к порту 0 означает запрос на динамическую генерацию неиспользуемого номера порта. Другими словами, номер порта, который вы фактически прослушиваете после этого запроса, не равен нулю. Там же комментарий об этом [linux kernel source]/net/ipv4/inet_connection_sock.cна inet_csk_get_port():

/* Obtain a reference to a local port for the given sock,
 * if snum is zero it means select any available local port.
 */

Что является стандартным соглашением Unix. Могут быть системы, которые фактически позволят использовать порт 0, но это будет считаться плохой практикой. Однако это поведение официально не указано в протоколах POSIX, IANA или TCP. 1 Вы можете найти это интересным .

Вот почему вы не можете разумно установить TCP-соединение с нулевым портом. Предположительно ncзнает об этом и сообщает вам, что вы делаете бессмысленный запрос. Если вы попробуете это в нативном коде:

int fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = 0;
inet_aton("127.0.0.1", &addr.sin_addr);
if (connect(fd, (const struct sockaddr*)&addr, sizeof(addr)) == -1) {
    fprintf(stderr,"%s", strerror(errno));
}    

Вы получаете ту же ошибку, что пытаетесь подключиться к любому другому недоступному порту: ECONNREFUSED«Отказано в соединении». Итак, в ответ на:

Где в системе это обрабатывается? В стеке TCP ядра ОС?

Возможно нет; это не требует специальной обработки. То есть, если вы можете найти систему, которая позволяет связывать и прослушивать порт 0, вы, вероятно, можете подключиться к нему.


1. Но IANA действительно относятся к нему как «Reserved» ( смотрите здесь ). Это означает, что этот порт не должен использоваться в сети. Это нормально с точки зрения соглашения о динамическом присваивании (так как оно фактически не будет использоваться). Предусматривая это как конкретную цель, вероятно, выходит за рамки IANA; по сути, операционные системы могут делать с ними все, что хотят, в том числе и ничего.

лютик золотистый
источник
Это похоже на ту же идею, что и адрес 0.0.0.0 в ipv4. Зарезервированное значение, используемое ОС и программами для специальных целей. По аналогии, в радио есть зарезервированные частоты, которые никто не использует для передач, но которые используются внутри оборудования.
Ctrl-Alt-Delor
1
@richard no, 0.0.0.0 имеет другое значение;) он используется для обозначения недопустимой, неизвестной или неприменимой цели или как «широковещательный»
AndreaCi
2
@AndreaCi не транслировалось 255.255.255.255?
фрик с трещоткой
4
@ratchetfreak 255.255.255.255 транслируется. 0.0.0.0 имеет два значения в зависимости от контекста. В программировании это синоним w / INADDR_ANY, на что ссылается Ричард (система заменит его значением по умолчанию). Но на самом деле использование адреса в сети, по-видимому, имеет последствия, о которых Андреа упоминает (за исключением того, что он не настолько понятен, как «широковещательный»): en.wikipedia.org/wiki/0.0.0.0
goldilocks
5

Использование порта 0 запускает операционную систему для поиска и выделения следующего доступного порта. Это исключает необходимость жесткого кодирования определенного порта или поиска доступного порта. Моя система Mint Linux возвращается

nc: port range not valid

в

nc localhost 0 
MichaelJohn
источник
2

nc -l 0попросит ОС прослушивать порт 0. Но, как отмечалось выше, большинство операционных систем увидят 0 и вызовут свои особые обычаи для выбора порта с положительным номером для вашего приложения, поэтому в ncконечном итоге прослушивается какой-либо порт, например 56514.

MC17
источник
большинство операционных систем, хорошо, которые не делают?
Барлоп