listen () без вызова bind () - PullRequest
       24

listen () без вызова bind ()

9 голосов
/ 12 апреля 2009

Я попробовал следующее:

int sockfd = socket(...);
listen(sockfd, 10);
accept(sockfd, ...);

Ни один из вызовов не прошел, и программа просто начала блокировать, как будто я вызвал bind (). Что будет в этом случае? Будет ли невозможно получить соединение, так как у него нет локального адреса или порта? Или ему неявно был назначен локальный адрес и порт, и теперь он прослушивает их? Если так, как я могу получить, что это такое?

Ответы [ 3 ]

11 голосов
/ 12 апреля 2009

Вызовы работают, но, поскольку вы не связали сокет явно, операционная система или системная библиотека неявно назначили вам порт и привязку по умолчанию (точно так же, как при вызове connect(2) без вызова bind(2) первый). Кроме того, так как вы ранее спрашивали о TCP, я предполагаю, что вы говорите об интернет-сокетах здесь.

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

Как Джон упоминает в комментарии, вы можете использовать getsockname(2), чтобы найти имя связанного сокета. Вот краткий пример:

// ...

// Create socket and set it to listen (we ignore error handling for brevity)
int sock = socket(AF_INET, SOCK_STREAM, 0);
listen(sock, 10);

// Sometime later we want to know what port and IP our socket is listening on
socklen_t addr_size = sizeof(struct sockaddr_in);
struck sockaddr_in addr;
getsockname(sock, (struct sockaddr *)&addr, &addr_size);

addr теперь будет содержать IP-адрес и порт, который прослушивает ваш сокет.

3 голосов
/ 12 апреля 2009

Как уже упоминалось, ОС назначит порт, если вы его не связываете (). Вы можете использовать вызов getsockname () после listen (), чтобы увидеть, какой адрес / порт назначен. Затем, если вы сообщили этот адрес / порт клиенту, он может подключиться.

Так что имеет смысл, что это работает. Вы могли бы написать программу, где это было бы интересно.

0 голосов
/ 12 апреля 2009

Я подозреваю, что вы никогда не получите соединение. Вы можете проверить, прослушивается ли новый сокет, выполнив эквивалент «netstat -an» в вашей ОС до и после запуска программы.

Я пробовал то же самое в C #:

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Listen(1);
socket.Accept();

Во второй строке я получаю исключение, которое окольным путем сообщает мне, что требуется привязка. Это, конечно, прекрасно работает с:

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(new IPEndPoint(IPAddress.Loopback, 4567));
socket.Listen(1);
socket.Accept();

Я также тестировал с сокетом Udp, и то же самое: Windows не удовлетворена вызовом Listen, если не было выполнено связывание. Поскольку вызовы сокетов .Net являются просто оболочкой для Winsock, такое поведение, вероятно, будет одинаковым для всех производных библиотек Winsock в Windows.

...