如何使用套接字地址获取自己的IP地址?

我想获得我的程序启动的计算机的IP地址,然后将其发送到客户端,但我总是得到0.0.0.1,而不是真正的IP地址(例如127.0.0.1)。

我目前能够获得端口,但不是IP地址。

我怎么才能得到它?

最好的解决办法是能够用sockaddr_in来获得它。 这是我目前正在做的事情:

 int open_connection(char* ip, int* port) { int sock; struct sockaddr_in sin; socklen_t len; int i; i = 0; len = sizeof(sin); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) return (-1); bzero(&sin, sizeof(struct sockaddr_in)); sin.sin_family = AF_INET; if (bind(sock, (struct sockaddr *) &sin, sizeof(sin)) != 0) perror("Error on bind"); if (getsockname(sock, (struct sockaddr *)&sin, &len) != 0) perror("Error on getsockname"); strcpy(ip, inet_ntoa(sin.sin_addr)); // IP = 0.0.0.0 *port = sin.sin_port; return (sock); } 

编辑:我明白我的思维方式是错误的。 所以我的问题是:什么是获得自己的IP地址的最佳途径?

Solutions Collecting From Web of "如何使用套接字地址获取自己的IP地址?"

bind()套接字bind()到0.0.0.0时,这是调用getsockname()时套接字可用的唯一IP。 这意味着套接字绑定到所有本地接口。 为了从一个套接字获得一个特定的IP,它必须绑定到一个特定的IP。

无论如何,使用套接字API获取机器的本地IP是错误的方法。 常见的错误是使用gethostbyname()getaddrinfo()来获取本地IP列表。 通常这是有效的,但它有一些可能导致虚假信息的隐藏陷阱,但是人们往往忽略这个事实,或者甚至不知道它(首先我不知道它,但是然后我学得更好)。

相反,您确实应该使用平台特定的API来枚举本地网络接口。 这将提供更可靠的信息。 Windows具有GetAdaptersInfo()GetAdaptersAddresses() 。 其他平台有getifaddrs() 。 那些会告诉你哪些本地IP可用。 然后,您可以bind()一个套接字bind()到0.0.0.0,以便接受任何这些IP上的客户端,或bind()到特定的IP以仅接受该IP上的客户端。

套接字API允许您枚举分配给您的网络接口的IP地址,但是如果您从路由器后面连接到Internet,它不会告诉您“真正的IP”是什么。

知道的唯一方法就是在外面问别人。 多数民众赞成在如FileZilla FTP服务器这样的服务器。 他们会指示您将URL配置为服务器设置中的“ip.php”脚本,以便它可以询问Internet的公网IP地址,以便在被动模式下使用。

您也可以考虑使用STUN ,这是一种广泛用于VoIP的协议,用于发现公共IP。

你可以调用ioctl(sock,SIOCGIFADDR,adr)

看netdevice(7)