我認爲無法使用套接字來枚舉系統上的每個網絡接口及其分配的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