这是代码。它与此类似问题的代码相同:http://monkey.org/freebsd/archive/freebsd-stable/200401/msg00032.html。当我运行它时,我总是得到输出:
收听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;
}
答案 0 :(得分:23)
指定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,并且您将使用getsockname()
取回该特定IP。
答案 1 :(得分:1)
是的,如果将它绑定到LOOPBACK,则必须指定INADDR_LOOPBACK。 否则它将自身附加到0.0.0.0,它代表所有可用的网络接口。发出getnameinfo()时,我遇到了同样的问题。
答案 2 :(得分:0)
如其他答案所述,由于0.0.0.0
被指定为侦听套接字的主机地址,因此返回INADDR_ANY
。如果您认为在多宿主主机中,客户端连接可以通过这些接口中的任何一个进入(这应该报告?),这是有道理的
扩展这些答案;如果需要客户端连接的实际IP地址,请使用SOCKET
和accept()
返回的getsockname()
。这将提供客户端连接到的服务器上的接口地址。