getsockname всегда возвращает 0.0.0.0? - PullRequest
13 голосов
/ 22 апреля 2011

Вот код.Это то же самое, что и код из подобного вопроса: http://monkey.org/freebsd/archive/freebsd-stable/200401/msg00032.html. Когда я запускаю его, я всегда получаю вывод:

прослушивание 0.0.0.0:54493 или что-то в этом роде.Очевидно, порт меняется, но я понятия не имею, почему я продолжаю получать IP-адрес 0.0.0.0.Я что-то упустил?

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{
    int sock;
    int len = sizeof(struct sockaddr);
    struct sockaddr_in addr, foo;

    if((sock=socket(AF_INET, SOCK_STREAM, 0))<0)
    {
        exit(0);
    }

    memset(&addr, 0, sizeof(struct sockaddr_in));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(0);

    if(bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in))<0)
    {
        perror("bind");
        exit(0);
    }

    if(listen(sock, 5)<0)
    {
         perror("listen");
         exit(0);
    }

    getsockname(sock, (struct sockaddr *) &foo, &len);
    fprintf(stderr, "listening on %s:%d\n", inet_ntoa(foo.sin_addr), 
            ntohs(foo.sin_port));

    return 0;
}

Ответы [ 3 ]

23 голосов
/ 22 апреля 2011

Вы указываете INADDR_ANY, а не конкретный IP-адрес, поэтому он привязывается к шаблону (все интерфейсы) 0.0.0.0.Таким образом, когда вы звоните getsockname(), вы получаете ответ.

Если вы указали 0.0.0.0 в качестве IP-адреса, а не INADDR_ANY, вы получите то же самое поведение;Вы будете привязаны ко всем сетевым интерфейсам на машине.

Например, допустим, у вас есть только один сетевой интерфейс с назначенным ему IP 192.168.1.12.У вас также есть петля по умолчанию - 127.0.0.1

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

Если бы вы привязались к определенному IP-адресу, а не к INADDR_ANY, ваш процесс прослушивал бы только этот IP-адрес, и вы получили бы этот конкретный IP-адрес с помощью getsockname().

1 голос
/ 23 апреля 2013

Да, если вы связываете его с LOOPBACK, вам нужно указать INADDR_LOOPBACK. В противном случае он присоединяется к 0.0.0.0, который представляет все доступные сетевые интерфейсы. Я столкнулся с той же проблемой при вызове getnameinfo ().

0 голосов
/ 11 июля 2018

Как упоминалось в других ответах, возвращается 0.0.0.0, поскольку INADDR_ANY было указано в качестве адреса хоста для прослушивающего сокета.Это имеет смысл, если вы считаете, что в многодомном хосте клиентские соединения могут входить через любой из этих интерфейсов (так о чем следует сообщать?)

Расширение этих ответов;если требуется фактический IP-адрес клиентского соединения, используйте SOCKET, возвращенное с accept() с getsockname().Это предоставит адрес интерфейса на сервере, к которому подключен клиент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...