linux读取本地网口ip地址的简单方法,避免踩坑

最近项目中需要读取本地网口的ip地址,然后在网上搜索了一下相关的内容。发现网上一些方法不够严谨,在实际应用时出现了一些问题。下面是我结合网上例子修改后的代码,比较简单。有什么问题还望指出。

static int get_ip(const char *inf_name,char *ip)
{
	if((inf_name == NULL)||(ip == NULL))
	{
		DPRINT("get ip failed,empty inf_name or ip buff\n");
		return -1;
	}
	
	struct ifaddrs *ifc,*ifc_header;
	if(getifaddrs(&ifc)<0)
	{
		DPRINT("getifaddrs failed:%s\n",strerror(errno));
		return -1;
	}
	ifc_header = ifc;

	while (ifc != NULL)
	{
		//注意:CAN接口也是用socket,但是CAN没有IP地址,ifa_addr为空;这里要进行判断,否则会出现操作野指针的情况,导致Segmentation fault。 		
		if (ifc->ifa_addr != NULL)	
		{
			if (ifc->ifa_addr->sa_family==AF_INET && 0 == strcmp(ifc->ifa_name,inf_name))
			{
				inet_ntop(AF_INET, &((struct sockaddr_in *)ifc->ifa_addr)->sin_addr,ip,INET_ADDRSTRLEN);
				freeifaddrs(ifc_header);
				return 0;
			}
		}
		
		ifc=ifc->ifa_next;
	}
	freeifaddrs(ifc_header);
	DPRINT("%s not found\n",inf_name);
	return -1;
}

需要注意的地方:
1、为什么定义了ifc和ifc_header?
看一下man中的说明,getifaddrs函数用于创建一个网络接口地址的链表,并保存这个链表的头指针,通过遍历网络接口地址链表来找到你要获取ip的那个网口。如果定义一个ifaddrs地址类型,在遍历的时候一直在变。那么freeifaddrs()释放此地址的时候就会有问题,可能造成内存泄漏或操作野指针的情况。所以定义了两个,一个用于保存链表的header,用于释放链表。在这里插入图片描述2、ifa_next指向了链表中的下一个地址,当为链表最后一个元素时ifa_next为NULL。结构体中ifa_addr即为socket接口的地址。这里需要特别注意:can也是用的socket接口在遍历时同样会遍历到can接口,但是**can接口是没有IP地址的。故相应的ifc->ifa_addr为NULL。如果此时再去操作ifc->ifa_addr即出现操作空指针的情况,会导致Segmentation fault。**当然这种情况只会出现在设备中有socket can接口的时候。刚开始时没有考虑到这种情况,在电脑上运行的时候一切正常,放在我设备运行的时候一直都报错,百思不得其解。后来经过大神指点才恍然大悟。遍历到指定的接口后取出IP地址,否则打印错误信息。
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值