我认为无法使用套接字来枚举系统上的每个网络接口及其分配的IP地址。它是否正确?枚举分配给网络接口的每个IP地址
我的意思是,在Linux中,这可能是:
eth0: 192.168.1.5
wlan0: 192.168.0.5
lo: 127.0.0.1
我不在乎接口名称,只是分配的IP地址。
我记得过去在Windows中使用Win32(尽管我不记得如何)做过这个。但是有没有办法以便携的方式来做到这一点?
我认为无法使用套接字来枚举系统上的每个网络接口及其分配的IP地址。它是否正确?枚举分配给网络接口的每个IP地址
我的意思是,在Linux中,这可能是:
eth0: 192.168.1.5
wlan0: 192.168.0.5
lo: 127.0.0.1
我不在乎接口名称,只是分配的IP地址。
我记得过去在Windows中使用Win32(尽管我不记得如何)做过这个。但是有没有办法以便携的方式来做到这一点?
这里有一个良好的开端:
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <stdio.h>
void
print_sockaddr(struct sockaddr* addr,const char *name)
{
char addrbuf[128] ;
addrbuf[0] = 0;
if(addr->sa_family == AF_UNSPEC)
return;
switch(addr->sa_family) {
case AF_INET:
inet_ntop(addr->sa_family,&((struct sockaddr_in*)addr)->sin_addr,addrbuf,sizeof(addrbuf));
break;
case AF_INET6:
inet_ntop(addr->sa_family,&((struct sockaddr_in6*)addr)->sin6_addr,addrbuf,sizeof(addrbuf));
break;
default:
sprintf(addrbuf,"Unknown (%d)",(int)addr->sa_family);
break;
}
printf("%-16s %s\n",name,addrbuf);
}
void
print_ifaddr(struct ifaddrs *addr)
{
char addrbuf[128] ;
addrbuf[0] = 0;
printf("%-16s %s\n","Name",addr->ifa_name);
if(addr->ifa_addr != NULL)
print_sockaddr(addr->ifa_addr,"Address");
if(addr->ifa_netmask != NULL)
print_sockaddr(addr->ifa_netmask,"Netmask");
if(addr->ifa_broadaddr != NULL)
print_sockaddr(addr->ifa_broadaddr,"Broadcast addr.");
if(addr->ifa_dstaddr != NULL)
print_sockaddr(addr->ifa_dstaddr,"Peer addr.");
puts("");
}
int main(int argc,char *argv[])
{
struct ifaddrs *addrs,*tmp;
if(getifaddrs(&addrs) != 0) {
perror("getifaddrs");
return 1;
}
for(tmp = addrs; tmp ; tmp = tmp->ifa_next) {
print_ifaddr(tmp);
}
freeifaddrs(addrs);
return 0;
}
使用gethostname()
来检索机器的本地DNS名称,然后将该名称传递到gethostbyname()
以获取其本地IP地址。
如果操作系统支持IPv6,请查看getaddrinfo()
函数,而不是gethostbyname()
。
这里我手动编辑的主机名解析到我的静态LAN IP地址(可以说192.168.0.2),但究竟如何这个行为上的另一个系统?我的意思是...主机名解析为127.0.0.1还是默认使用哪个接口的IP? – conejoroy 2010-10-12 05:54:16
使用IP地址作为主机名调用'gethostbyname()'将不起作用,AFAIK。你可以使用'gethostbyaddr()',但是这会返回一个'hostent'结构,它只包含你最初指定的IP。要枚举可用的IP,您必须使用机器的实际主机名。否则,你将不得不使用操作系统特定的API来直接枚举网络接口(在Windows上,查看'GetAdapterAddresses()'和相关函数)。 – 2010-10-13 20:02:24
查看ioctl()
函数。如果我没有记错,你可以用它来获取任何接口的信息,以及获取可用的接口。
虽然我不记得正确的调用。与fcntl()
一样,它需要一个请求参数和确定其行为的变量参数。
在Linux上,通过NETLINK套接字访问该信息。请参阅libnetlink(3),netlink(7)和rtnetlink(7)的手册页。
这样做更简单一些,可以通过ioctl()来实现。 SIOCGIFCONF是你想要的。请参阅netdevice的手册页(7)。这一个适用于其他* nixes。
+1。不知道getifaddrs()/ freeifaddrs() – ninjalj 2010-10-11 21:26:31
优秀的答案! +1 – slezica 2010-10-12 01:19:56
这就是我所需要的,谢谢!但它只适用于Linux,我说得对吗? winapi相当于什么? – conejoroy 2010-10-12 06:03:08