getsockname总是返回0.0.0.0?

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

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

#include  #include  #include  #include  #include  #include  #include  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; } 

您指定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.0INADDR_ANY意味着您将绑定到这两个地址,而不是特定地址。 您将能够通过IP连接到您的流程。

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

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

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

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