头文件:
#include <linux/rtnetlink.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <string.h>
#include <QDebug>
#define BUFLEN 20480
#define NETWORK_TYPE_USB "usb0"
#define NETWORK_TYPE_ETH "eth0"
主程序实现:
void netLinkMonitor()
{
int fd, retval;
char buf[BUFLEN] = {0};
int len = BUFLEN;
struct sockaddr_nl addr;
struct nlmsghdr *nh;
struct ifinfomsg *ifinfo;
struct rtattr *attr;
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &len, sizeof(len));
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
addr.nl_groups = RTNLGRP_LINK;
bind(fd, (struct sockaddr*)&addr, sizeof(addr));
while ((retval = read(fd, buf, BUFLEN)) > 0)
{
for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, retval); nh = NLMSG_NEXT(nh, retval))
{
if (nh->nlmsg_type == NLMSG_DONE)
break;
// else if (nh->nlmsg_type == NLMSG_ERROR)
// return -1;
else if (nh->nlmsg_type != RTM_NEWLINK)
continue;
ifinfo = (struct ifinfomsg *)NLMSG_DATA(nh);
printf("%u: %s", ifinfo->ifi_index,
(ifinfo->ifi_flags & IFF_LOWER_UP) ? "up" : "down" );
attr = (struct rtattr*)(((char*)nh) + NLMSG_SPACE(sizeof(*ifinfo)));
len = nh->nlmsg_len - NLMSG_SPACE(sizeof(*ifinfo));
for (; RTA_OK(attr, len); attr = RTA_NEXT(attr, len))
{
if (attr->rta_type == IFLA_IFNAME)
{
printf(" %s", (char*)RTA_DATA(attr));
break;
}
}
printf("\n");
if(!strcmp((char*)RTA_DATA(attr), NETWORK_TYPE_USB)){
if((ifinfo->ifi_flags & IFF_LOWER_UP)){
//emit m_pInstance->usbNetworkIsChanged(true);
}else{
//emit m_pInstance->usbNetworkIsChanged(false);
}
}
if(!strcmp((char*)RTA_DATA(attr), NETWORK_TYPE_ETH)){
if((ifinfo->ifi_flags & IFF_LOWER_UP)){
//emit m_pInstance->ethNetworkIsChanged(true);
}else{
//emit m_pInstance->ethNetworkIsChanged(false);
}
}
}
}
}
对于网线或者wifi,usb等的状态监控十分有用,通过捕获不同的状态,用于应用的后续处理。