C语言 getockname 总是返回 0.0.0.0?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5759031/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
getsockname always returning 0.0.0.0?
提问by Brian Roach
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;
}
回答by Brian Roach
You specify INADDR_ANYrather 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.0as the IP address rather than INADDR_ANYyou 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.12assigned to it. You also have the loopback by default - 127.0.0.1
例如,假设您只有一个192.168.1.12分配有 IP 的网络接口。默认情况下您也有环回 -127.0.0.1
Using 0.0.0.0or INADDR_ANYmeans 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.0orINADDR_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().
回答by vishal_ratna
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() 调用时遇到了同样的问题。
回答by Ian
As mentioned in the other answers, 0.0.0.0is returned because INADDR_ANYwas 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 SOCKETreturned from accept()with getsockname(). This will provide the interface address on the server to which the client connected.
扩展这些答案;如果需要客户端连接的实际 IP 地址,请使用SOCKET从accept()with返回的getsockname()。这将提供客户端连接到的服务器上的接口地址。

