getsockname总是返回0.0.0.0?

时间:2022-10-16 11:03:45

Here is the code. It is the same as the code from this similar question: http://monkey.org/freebsd/archive/freebsd-stable/200401/msg00032.html. When I run it I always get the output:

这是代码。它与此类似问题的代码相同:http://monkey.org/freebsd/archive/freebsd-stable/200401/msg00032.html。当我运行它时,我总是得到输出:

listening on 0.0.0.0:54493 or something. Obviously the port changes, but I have no idea why I keep getting an IP address of 0.0.0.0. Am I missing something?

听取0.0.0.0:54493或其他什么。显然端口发生了变化,但我不知道为什么我一直在获得0.0.0.0的IP地址。我错过了什么吗?

#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 个解决方案

#1


22  

You specify INADDR_ANY rather than a specific IP address, so it binds to the wildcard (all interfaces) 0.0.0.0. So, when you call getsockname() that's what you get back.

您指定INADDR_ANY而不是特定的IP地址,因此它绑定到通配符(所有接口)0.0.0.0。所以,当你调用getsockname()时,你会得到回报。

If you specified 0.0.0.0 as the IP address rather than INADDR_ANY you would get the same behavior; you will bind to all network interfaces on the machine.

如果您指定0.0.0.0作为IP地址而不是INADDR_ANY,则会得到相同的行为;您将绑定到计算机上的所有网络接口。

For example, lets say you only have one network interface with the IP 192.168.1.12 assigned to it. You also have the loopback by default - 127.0.0.1

例如,假设您只有一个网络接口,并为其分配了IP 192.168.1.12。默认情况下你也有环回 - 127.0.0.1

Using 0.0.0.0 or INADDR_ANY means you'll be bound to both those addresses, rather than a specific one. You will be able to connect to to your process via either IP.

使用0.0.0.0或INADDR_ANY意味着您将绑定到这两个地址,而不是特定地址。您将能够通过IP连接到您的流程。

If you were to bind to a specific IP rather than INADDR_ANY, your process would only listen on that IP and you'd get back that specific IP with getsockname().

如果您要绑定到特定的IP而不是INADDR_ANY,那么您的进程只会侦听该IP,并且您将使用getsockname()返回该特​​定的IP。

#2


1  

Yes, if you bind it to a LOOPBACK , u have to specify INADDR_LOOPBACK. Otherwise it attaches itself to 0.0.0.0 which represents all the network interfaces available. I was facing the same problem, while issuing getnameinfo() call.

是的,如果将它绑定到LOOPBACK,则必须指定INADDR_LOOPBACK。否则它将自身附加到0.0.0.0,它表示所有可用的网络接口。发出getnameinfo()时,我遇到了同样的问题。

#3


0  

As mentioned in the other answers, 0.0.0.0 is returned because INADDR_ANY was specified as the host address for the listening socket. This makes sense if you think that, in a multi-homed host, client connections could come in on any of those interfaces (so which should be reported?)

如其他答案中所述,返回0.0.0.0,因为INADDR_ANY被指定为侦听套接字的主机地址。如果您认为在多宿主主机中,客户端连接可以进入任何这些接口(那么应该报告哪些?),这是有道理的。

Expanding on those answers; if the actual IP address of a client connection is required, use the SOCKET returned from accept() with getsockname(). This will provide the interface address on the server to which the client connected.

扩展这些答案;如果需要客户端连接的实际IP地址,请使用accept()返回的SOCKET和getsockname()。这将在客户端连接的服务器上提供接口地址。

#1


22  

You specify INADDR_ANY rather than a specific IP address, so it binds to the wildcard (all interfaces) 0.0.0.0. So, when you call getsockname() that's what you get back.

您指定INADDR_ANY而不是特定的IP地址,因此它绑定到通配符(所有接口)0.0.0.0。所以,当你调用getsockname()时,你会得到回报。

If you specified 0.0.0.0 as the IP address rather than INADDR_ANY you would get the same behavior; you will bind to all network interfaces on the machine.

如果您指定0.0.0.0作为IP地址而不是INADDR_ANY,则会得到相同的行为;您将绑定到计算机上的所有网络接口。

For example, lets say you only have one network interface with the IP 192.168.1.12 assigned to it. You also have the loopback by default - 127.0.0.1

例如,假设您只有一个网络接口,并为其分配了IP 192.168.1.12。默认情况下你也有环回 - 127.0.0.1

Using 0.0.0.0 or INADDR_ANY means you'll be bound to both those addresses, rather than a specific one. You will be able to connect to to your process via either IP.

使用0.0.0.0或INADDR_ANY意味着您将绑定到这两个地址,而不是特定地址。您将能够通过IP连接到您的流程。

If you were to bind to a specific IP rather than INADDR_ANY, your process would only listen on that IP and you'd get back that specific IP with getsockname().

如果您要绑定到特定的IP而不是INADDR_ANY,那么您的进程只会侦听该IP,并且您将使用getsockname()返回该特​​定的IP。

#2


1  

Yes, if you bind it to a LOOPBACK , u have to specify INADDR_LOOPBACK. Otherwise it attaches itself to 0.0.0.0 which represents all the network interfaces available. I was facing the same problem, while issuing getnameinfo() call.

是的,如果将它绑定到LOOPBACK,则必须指定INADDR_LOOPBACK。否则它将自身附加到0.0.0.0,它表示所有可用的网络接口。发出getnameinfo()时,我遇到了同样的问题。

#3


0  

As mentioned in the other answers, 0.0.0.0 is returned because INADDR_ANY was specified as the host address for the listening socket. This makes sense if you think that, in a multi-homed host, client connections could come in on any of those interfaces (so which should be reported?)

如其他答案中所述,返回0.0.0.0,因为INADDR_ANY被指定为侦听套接字的主机地址。如果您认为在多宿主主机中,客户端连接可以进入任何这些接口(那么应该报告哪些?),这是有道理的。

Expanding on those answers; if the actual IP address of a client connection is required, use the SOCKET returned from accept() with getsockname(). This will provide the interface address on the server to which the client connected.

扩展这些答案;如果需要客户端连接的实际IP地址,请使用accept()返回的SOCKET和getsockname()。这将在客户端连接的服务器上提供接口地址。