求助:如何在程序中得到本机的多个IP地址及其子网掩码?

sliant 2004-04-09 03:58:08
就像 windows2000 下的 ipconfig.exe /all
或者 linux 下的 ifconfig 命令一样
大家能给出 C/C++/JAVA 代码吗?
...全文
257 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
sliant 2004-04-15
  • 打赏
  • 举报
回复
linux 下的 ifconfig 源码在 http://freshmeat.net/projects/net-tools/
我大致看了一下,ifconfig.c 就是 ifconfig 的源代码,里面的 main() 函数首先分析命令行参数,如果没有参数就会调用 ifconfig.c 中的 if_print() 然后退出。
ifconfig.c 中的 if_print() 首先从 /proc/net/dev 文件中读取所有的 ip 信息(这里只有每个ip的流量统计等数据,没有ip地址和掩码);然后调用 lib/interface.c 中的 do_if_fetch() ,后者又调用 lib/interface.c 中的 if_fetch() 得到 ip 地址和掩码等信息。
lib/interface.c 中的 if_fetch() 得到 ip 地址和掩码使用的是一堆 ioctl() 方法:
ioctl(skfd, SIOCGIFFLAGS, &ifr)
ioctl(skfd, SIOCGIFHWADDR, &ifr)
ioctl(skfd, SIOCGIFMETRIC, &ifr)
ioctl(skfd, SIOCGIFMTU, &ifr)
ioctl(skfd, SIOCGOUTFILL, &ifr)
ioctl(skfd, SIOCGKEEPALIVE, &ifr)
ioctl(skfd, SIOCGIFMAP, &ifr)
ioctl(skfd, SIOCGIFTXQLEN, &ifr)
ioctl(skfd, SIOCGIFADDR, &ifr) //ip地址
ioctl(skfd, SIOCGIFBRDADDR, &ifr)
ioctl(skfd, SIOCGIFNETMASK, &ifr) //掩码
...
不过我对 linux 网络编程都不熟,没有细看,也没有试验这些函数
HuYuguang 2004-04-15
  • 打赏
  • 举报
回复
getadaptersinfo 是iphlpapi输出的函数。最后落实到给\\device\\tcp发送ioctl:IOCTL_TCP_QUERY_INFORMATION_EX


RedGuest 2004-04-14
  • 打赏
  • 举报
回复
有个比较通用的方法是通过snmp协议得到标准mib库RFC1213中的一个节点,就是所有的IP和其掩码等等信息,这样对所有的系统都可以使用,JAVA直接可以实现了,不用本地方法,不过有个问题就是,并不是所有的机子都开了snmp服务,但是我以前在一家公司做的时候用过一个C++的代码,就是这么实现的,而且,据介绍,连window的ipconfig都是这么实现的,但是HuYuguang(郁闷的战士) 所说的API又是如何实现的呢?是不是也是通过snmp来得到的,还是window内核直接实现的,就不得而知,希望高手能给点解释哦:) 谢谢了
Asiafly 2004-04-13
  • 打赏
  • 举报
回复
gethostname() 得到的数据存储为一个结构,就象 hell190109() 所说的,把h_addr_list结构里面的内容循环输出就可以。
boodweb 2004-04-13
  • 打赏
  • 举报
回复
呵呵,最近我遇到了跟楼主差不多的问题,不过我发现在我用的那台机器上(redhat,局欲望)用gethostname只能得到叫'localhost'的域名,再用gethostbyname结果只有127.0.0.1,不知怎么解决,共同探讨一下吧
难道可以没有本地域名?
sliant 2004-04-12
  • 打赏
  • 举报
回复
感谢 HuYuguang(郁闷的战士) 的代码,我试了一下,GetAdaptersInfo() 确实就是最核心的函数调用。另外一个网卡可能绑定多个ip,所以AdapterInfo[i].IpAddressList是一个链表。我准备把 GetAdaptersInfo() 写成 .dll 封装成 java 的本地方法。

HuYuguang(郁闷的战士) 你对 linux ifconfig 的源代码有了解吗?

http://freshmeat.net/projects/net-tools/ 不知道谁有兴趣去读这个源代码,把获取本机多个ip的部分讲来听听,要是能封装成一个简单的函数调用就更好了
theoldman 2004-04-10
  • 打赏
  • 举报
回复
gethostname()得到本机的名字,然后用gethostbyname()获取本机的信息,这些信息中包含本机的IP地址。
fierygnu 2004-04-10
  • 打赏
  • 举报
回复
?用本机名调用gethostbyname不就行了吗?
获取IP和掩码后计算网络地址,与本地网络地址比较。
HuYuguang 2004-04-10
  • 打赏
  • 举报
回复
这是我的一个函数代码片断,我去掉了一些不相关的。
注:msdn建议GetAdaptersInfo的使用方法如下:
1、先传递NULL,0进去,然后得到所需要的内存数量
2、再次调用
该方法在大多数时候工作良好,但是的确某些时候不工作,我也不知道是什么原因,猜想和
用户的机器的FIREWALL或者别的软件有关。
此外,这样会导致该函数内部产生一个exception,我发现在某些时候——不知道什么原因,
这个exception没有被该函数自己捕获,也会导致问题。
因此我用了一个静态数组。


DWORD dwNumNIC = 0;
IP_ADAPTER_INFO AdapterInfo[32]; // should someone has more than 32 adapters?
DWORD dwOutBufLen = sizeof(AdapterInfo);
CString strZ;

memset(AdapterInfo,0,dwOutBufLen);

if(ERROR_SUCCESS!=GetAdaptersInfo(AdapterInfo,&dwOutBufLen))
{
strZ.LoadString(IDS_GETADAPTERSINFO_FAIL);
Log::printgui(2,"%s\n",(LPCTSTR)strZ);
return false;
}

dwNumNIC = dwOutBufLen/sizeof(IP_ADAPTER_INFO);

PIP_ADDR_STRING ipaddr;
for(DWORD i=0;i<dwNumNIC ;i++)
{
ipaddr = &AdapterInfo[i].IpAddressList;
while(ipaddr)
{
ULONG ip = ntohl(inet_addr((char*)(ipaddr->IpAddress.String)));
ULONG ipmask = ntohl(inet_addr((char*)(ipaddr->IpMask.String)));

ipaddr = ipaddr->Next;
}
}
sliant 2004-04-10
  • 打赏
  • 举报
回复
不行啊 这里的问题是多个ip多个域名
gethostname() 及类似的调用只能得到主域名,具体是多个域名中的哪一个,就要看操作系统的具体实现了。比如我的windows2000,做局域网的网关,所以我有两个IP及域名:
局域网机器名 mycomputer 对应IP 192.168.0.1
连接到internet域名 myname.net 对应一个动态IP如 61.229.0.78
我在java中调用getlocalhost,得到的是局域网机器名。
一个机器多IP,这个应该不是 socket 编程能解决的问题,而是和操作系统的支持相关的,只能去看 ifconfig 之类的源代码
sliant 2004-04-09
  • 打赏
  • 举报
回复
gethostbyname() 是解析一个域名对应的多个 IP
这里我是想得到本机的多个IP

比如,本机是局域网的网关,有局域网址 192.168.0.1 ,还有拨号上网的动态 IP ,共计2个IP,根据各自的子网掩码就可以分辨哪些是局域网址、哪些是真实 internet 网址

有办法吗?

另外,我找了一些资料,好像 windows 和 linux 不同,多ip和操作系统内核相关的。
这是 windows ipconfig 的简单实现源码
http://www.codeproject.com/internet/netcfg.asp
这是 linux ifconfig 的源代码
http://freshmeat.net/projects/net-tools/
大家谁熟悉网络编程的,能不能把这两个都写成动态连接库,造福一下群众啊
qqpopo668 2004-04-09
  • 打赏
  • 举报
回复
我有但是delphi的,支持你
hell190109 2004-04-09
  • 打赏
  • 举报
回复
采用下面的代码可以获得本机IP地址:
char szHostName[128];

if( gethostname(szHostName, 128) == 0 )
{
// Get host adresses
struct hostent * pHost;
int i;

pHost = gethostbyname(szHostName);

for( i = 0; pHost!= NULL && pHost->h_addr_list[i]!= NULL; i++ )
{
CString str;
int j;

for( j = 0; j < pHost->h_length; j++ )
{
CString addr;

if( j > 0 )
str += ".";

addr.Format("%u", (unsigned int)((unsigned
char*)pHost->h_addr_list[i])[j]);
str += addr;
}
// str now contains one local IP address - do whatever you want to do with it (probably add it to a list)
}
}
tianxiangyuan 2004-04-09
  • 打赏
  • 举报
回复
使用gethostbyname得到的结果就包含所有的ip地址。请参考相关结构的说明。

4,358

社区成员

发帖
与我相关
我的任务
社区描述
通信技术相关讨论
社区管理员
  • 网络通信
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧