您建议的方法依赖于“正确”的本地主机名和“正确”配置的 DNS 系统。我将“正确”放在引号中,因为拥有未向 DNS 注册的本地主机名对于任何目的都是完全有效的,除了您的程序。
如果你有一个连接的套接字(或者可以生成一个连接的套接字),我建议你使用getsockname()
找到a本地IP地址。 (注:不the本地 IP 地址——您可以有多个。)
这是一个执行此操作的示例程序。显然,大部分都连接到google.com
并打印结果。只需致电getsockname()
与你的问题密切相关。
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
int main(int ac, char **av) {
addrinfo *res;
if(getaddrinfo("google.com", "80", 0, &res)) {
fprintf(stderr, "Can't lookup google.com\n");
return 1;
}
bool connected = false;
for(; res; res=res->ai_next) {
int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if(fd < 0) {
perror("socket");
continue;
}
if( connect(fd, res->ai_addr, res->ai_addrlen) ) {
perror("connect");
close(fd);
continue;
}
sockaddr_in me;
socklen_t socklen = sizeof(me);
if( getsockname(fd, (sockaddr*)&me, &socklen) ) {
perror("getsockname");
close(fd);
continue;
}
if(socklen > sizeof(me)) {
close(fd);
continue;
}
char name[64];
if(getnameinfo((sockaddr*)&me, socklen, name, sizeof name, 0, 0, NI_NUMERICHOST)) {
fprintf(stderr, "getnameinfo failed\n");
close(fd);
continue;
}
printf("%s ->", name);
if(getnameinfo(res->ai_addr, res->ai_addrlen, name, sizeof name, 0, 0, NI_NUMERICHOST)) {
fprintf(stderr, "getnameinfo failed\n");
close(fd);
continue;
}
printf("%s\n", name);
close(fd);
}
}