Linux下C获取所有可用网卡信息
在Linux下开发网络程序时,经常会遇到需要取本地网络接口名、IP、广播地址
、子网掩码或者MAC地址等信息的需求,最常见的办法是配合宏SIOCGIFHWADDR、
SIOCGIFADDR、SIOCGIFBRDADDR与SIOCGIFNETMASK作为参数调用
在Linux下开发网络程序时,经常会遇到需要取本地网络接口名、IP、广播地址
、子网掩码或者MAC地址等信息的需求,最常见的办法是配合宏SIOCGIFHWADDR、
SIOCGIFADDR、SIOCGIFBRDADDR与SIOCGIFNETMASK作为参数调用函数ioctl分别获
得MAC地址、IP地址、广播地址与子网掩码来实现。一次性获取此类信息的C语言
代码实现如下。
海姹网(网址:http://www.seacha.com),标签:Linux下C获取所有可用网卡信
息, 网卡,ioctl,IP
#include <stdio.h>
#include <string.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <errno.h>
int getLocalInfo(void)
{
int fd;
int interfaceNum = 0;
struct ifreq buf[16];
struct ifconf ifc;
struct ifreq ifrcopy;
char mac[16] = {0};
char ip[32] = {0};
char broadAddr[32] = {0};
char subnetMask[32] = {0};
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("socket");
close(fd);
return -1;
}
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = (caddr_t)buf;
if (!ioctl(fd, SIOCGIFCONF, (char *)&ifc))
{
interfaceNum = ifc.ifc_len / sizeof(struct ifreq);
printf("interface num = %dn", interfaceNum);
while (interfaceNum-- > 0)
{
printf("ndevice name: %sn", buf[interfaceNum].ifr_name);
//ignore the interface that not up or not runing
ifrcopy = buf[interfaceNum];
if (ioctl(fd, SIOCGIFFLAGS, &ifrcopy))
{
printf("ioctl: %s [%s:%d]n", strerror(errno),
__FILE__, __LINE__);
close(fd);
return -1;
}
//get the mac of this interface
if (!ioctl(fd, SIOCGIFHWADDR, (char *)(&buf
[interfaceNum])))
{
memset(mac, 0, sizeof(mac));
snprintf(mac, sizeof(mac), "%02x%02x%02x%02x%02x%02x",
(unsigned char)buf
[interfaceNum].ifr_hwaddr.sa_data[0],
(unsigned char)buf
[interfaceNum].ifr_hwaddr.sa_data[1],
(unsigned char)buf
[interfaceNum].ifr_hwaddr.sa_data[2],
(unsigned char)buf
[interfaceNum].ifr_hwaddr.sa_data[3],
(unsigned char)buf
[interfaceNum].ifr_hwaddr.sa_data[4],
(unsigned char)buf
[interfaceNum].ifr_hwaddr.sa_data[5]);
printf("device mac: %sn", mac);
}
else
{
printf("ioctl: %s [%s:%d]n", strerror(errno),
__FILE__, __LINE__);
close(fd);
return -1;
}
//get the IP of this interface
if (!ioctl(fd, SIOCGIFADDR, (char *)&buf[interfaceNum]))
{
snprintf(ip, sizeof(ip), "%s",
(char *)inet_ntoa(((struct sockaddr_in *)&(buf
[interfaceNum].ifr_addr))->sin_addr));
printf("device ip: %sn", ip);
}
else
{
printf("ioctl: %s [%s:%d]n", strerror(errno),
__FILE__, __LINE__);
close(fd);
return -1;
}
//get the broad address of this interface
if (!ioctl(fd, SIOCGIFBRDADDR, &buf[interfaceNum]))
{
snprintf(broadAddr, sizeof(broadAddr), "%s",
(char *)inet_ntoa(((struct sockaddr_in *)&(buf
[interfaceNum].ifr_broadaddr))->sin_addr));
printf("device broadAddr: %sn", broadAddr);
}
else
{
printf("ioctl: %s [%s:%d]n", strerror(errno),
__FILE__, __LINE__);
close(fd);
return -1;
}
//get the subnet mask of this interface
if (!ioctl(fd, SIOCGIFNETMASK, &buf[interfaceNum]))
{
snprintf(subnetMask, sizeof(subnetMask), "%s",
(char *)inet_ntoa(((struct sockaddr_in *)&(buf
[interfaceNum].ifr_netmask))->sin_addr));
printf("device subnetMask: %sn", subnetMask);
}
else
{
printf("ioctl: %s [%s:%d]n", strerror(errno),
__FILE__, __LINE__);
close(fd);
return -1;
}
}
}
else
{
printf("ioctl: %s [%s:%d]n", strerror(errno), __FILE__,
__LINE__);
close(fd);
return -1;
}
close(fd);
return 0;
}
int main(void)
{
getLocalInfo();
return 0;
}
使用ioctl函数虽然可以获取所有的信息,但是使用起来比较麻烦,如果不需要
获取MAC地址,那么使用getifaddrs函数来获取更加方便与简洁。值得一提的是
,在MacOS或iOS系统上(如iPhone程序开发),上述iotcl函数没法获得mac地址
跟子网掩码,这个使用,使用getifaddrs函数便更有优势了。下面是使用
getiaddrs函数获取网卡信息的C语言代码实现。
#include <stdio.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
int getSubnetMask()
{
struct sockaddr_in *sin = NULL;
struct ifaddrs *ifa = NULL, *ifList;
if (getifaddrs(&ifList) < 0)
{
return -1;
}
for (ifa = ifList; ifa != NULL; ifa = ifa->ifa_next)
{
if(ifa->ifa_addr->sa_family == AF_INET)
{
printf("n>>> interfaceName: %sn", ifa->ifa_name);
sin = (struct sockaddr_in *)ifa->ifa_addr;
printf(">>> ipAddress: %sn", inet_ntoa(sin->sin_addr));
sin = (struct sockaddr_in *)ifa->ifa_dstaddr;
printf(">>> broadcast: %sn", inet_ntoa(sin->sin_addr));
sin = (struct sockaddr_in *)ifa->ifa_netmask;
printf(">>> subnetMask: %sn", inet_ntoa(sin->sin_addr));
}
}
freeifaddrs(ifList);
return 0;
}
int main(void)
{
getSubnetMask();
return 0;
}
========
linux下获取主机IP地址的源码
支持多网卡,主要是使用ioctl函数系统调用实现,通过指定设备名实现指定功能.
之前使用socket()函数,获取文件描述符.在此基础可以很轻松的扩展,如获取net
mask,MAC address等 #include stdio.h #include sys/types.
支持多网卡,主要是使用ioctl函数系统调用实现,通过指定设备名实现指
定功能.之前使用socket()函数,获取文件描述符.在此基础可以很轻松的扩展,如
获取net mask,MAC address等
#include <stdio.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <net/if_arp.h>
#define MAXINTERFACES 16
int main(void)
{
register int fd, intrface;
struct ifreq buf[MAXINTERFACES];
struct ifconf ifc;
if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
{
return -1;
}
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = (caddr_t) buf;
if (ioctl (fd, SIOCGIFCONF, (char *) &ifc) < 0)
{
return -1;
}
intrface = ifc.ifc_len / sizeof (struct ifreq);
printf("number of interface is: %d\n",intrface);
while (intrface-- > 0)
{
printf ("net device %s\n", buf[intrface].ifr_name);
if ((ioctl (fd, SIOCGIFFLAGS, (char *) &buf[intrface])) < 0)
{
continue;
}
if (buf[intrface].ifr_flags & IFF_PROMISC)
{
puts ("the interface is PROMISC");
}
else
{
if (buf[intrface].ifr_flags & IFF_UP)
{
puts("the interface status is UP");
}
else
{
if (buf[intrface].ifr_flags & IFF_RUNNING)
puts("the interface status is RUNNING");
}
}
if (!(ioctl (fd, SIOCGIFADDR, (char *) &buf[intrface])))
{
puts ("IP address is:");
puts(inet_ntoa(((struct sockaddr_in*)(&buf
[intrface].ifr_addr))->sin_addr));
puts("");
}
else
{
char str[256];
sprintf (str, "cpm: ioctl device %s", buf
[intrface].ifr_name); perror (str);
}
}
close (fd);
return 0;
}
========
linux 系统获取网络ip, mask, gateway, dns信息小程序
net_util.c
#define WIRED_DEV "eth0"
#define WIRELESS_DEV "ra0"
#define PPPOE_DEV "ppp0"
#define DEBUG_PRT(fmt, arg...) printf(fmt,##arg)
/**
* get ip address.
* @param net_dev net device.
* @param ipaddr a pointer to save ip address.
* @return 0 success, or fail.
*/
int get_ipaddr(const char *net_dev, char *ipaddr)
{
struct ifreq ifr;
int fd = 0;
struct sockaddr_in *pAddr;
if((NULL == net_dev) || (NULL == ipaddr))
{
DEBUG_PRT("illegal call function SetGeneralIP! \n");
return -1;
}
if((fd = socket(AF_INET,SOCK_DGRAM,0)) < 0)
{
DEBUG_PRT("open socket failed \n");
return -1;
}
memset(&ifr,0,sizeof(ifr));
strcpy(ifr.ifr_name, net_dev);
if(ioctl(fd, SIOCGIFADDR, &ifr) < 0)
{
DEBUG_PRT("SIOCGIFADDR socket failed \n");
close(fd);
return -1;
}
pAddr = (struct sockaddr_in *)&(ifr.ifr_addr);
strcpy(ipaddr, inet_ntoa(pAddr->sin_addr));
close(fd);
return 0;
}
/**
* get gateway.
* @param gateway a pointer to save geteway.
* @return none.
*/
void get_gateway(ITI_CHAR *gateway)
{
char buf[1024]={0};
char *p = NULL;
char *q = NULL;
int count = 0;
if(NULL == gateway)
{
DEBUG_PRT("gateway is NULL \n");
return;
}
cmd_run("route | grep default", buf, 1024);
if(0 == strlen(buf))
{
DEBUG_PRT("get gateway error \n");
return;
}
p = strstr2(buf, "default");
q = p;
while(*q == ' ')
{
q++;
}
p = q;
while(*p != ' ')
{
p++;
count++;
}
if(NULL != q)
{
memcpy(gateway, q, count);
}
gateway[count] = '\0';
}
/**
* get mask.
* @param net_dev net device.
* @param mask a pointer to save mask.
* @return none.
*/
void get_mask(const char *net_dev, ITI_CHAR *mask)
{
char buf[1024]={0};
char *p = NULL;
if(NULL == mask)
{
DEBUG_PRT("mask is NULL \n");
return;
}
if(0 == (memcmp(WIRED_DEV, net_dev, sizeof(WIRED_DEV))))
{
cmd_run("ifconfig eth0 | grep Mask", buf, 1024);
}
else if(0 == (memcmp(WIRELESS_DEV, net_dev, sizeof(WIRELESS_DEV))))
{
cmd_run("ifconfig ra0 | grep Mask", buf, 1024);
}
else if(0 == (memcmp(PPPOE_DEV, net_dev, sizeof(PPPOE_DEV))))
{
cmd_run("ifconfig ppp0 | grep Mask", buf, 1024);
}
else
{
DEBUG_PRT("net device not support \n");
return;
}
if(0 == strlen(buf))
{
DEBUG_PRT("get mask error \n");
return;
}
p = strstr2(buf, "Mask:");
if(NULL == p)
{
DEBUG_PRT("get mask error \n");
return;
}
strcpy(mask, p);
}
/**
* get dns.
* @param dns1 a pointer to save first dns.
* @param dns2 a pointer to save second dns.
* @return 0 success, or fail.
*/
int get_dns(char *dns1, char *dns2)
{
int fd = -1;
int size = 0;
char strBuf[100];
char tmpBuf[100];
int buf_size = sizeof(strBuf);
char *p = NULL;
char *q = NULL;
int i = 0;
int j = 0;
int count = 0;
fd = open("/etc/resolv.conf", O_RDONLY);
if(-1 == fd)
{
DEBUG_PRT("%s open error \n", __func__);
return -1;
}
size = read(fd, strBuf, buf_size);
if(size < 0)
{
DEBUG_PRT("%s read file len error \n", __func__);
close(fd);
return -1;
}
strBuf[buf_size] = '\0';
close(fd);
while(i < buf_size)
{
if((p = strstr2(&strBuf[i], "nameserver")) != NULL)
{
j++;
p += 1;
count = 0;
memset(tmpBuf, 0xff, 100);
memcpy(tmpBuf, p, 100);
tmpBuf[sizeof(tmpBuf) -1 ] = '\0';
q = p;
while(*q != '\n')
{
q++;
count++;
}
i += (sizeof("nameserver") + count);
if(1 == j)
{
memcpy(dns1, p, count);
dns1[count]='\0';
}
else if(2 == j)
{
memcpy(dns2, p, count);
dns2[count]='\0';
}
}
else
{
i++;
}
}
return 0;
}
main.c
void main(void)
{
#define WIRED_DEV "eth0"
#define WIRELESS_DEV "ra0"
#define PPPOE_DEV "ppp0"
char buf[1024] = {'\0'};
extern int get_ipaddr(const char *net_dev, char *ipaddr);
get_ipaddr(WIRED_DEV, buf);
printf("get_ipaddr: %s \n", buf);
memset(buf, '\0', sizeof(buf));
extern void get_mask(const char *net_dev, ITI_CHAR *mask);
get_mask(WIRED_DEV, buf);
printf("get_mask: %s \n", buf);
memset(buf, '\0', sizeof(buf));
extern void get_gateway(ITI_CHAR *gateway);
get_gateway(buf);
printf("get_gateway: %s \n", buf);
memset(buf, '\0', sizeof(buf));
extern int get_dns(char *dns1, char *dns2);
get_dns(buf, &buf[100]);
printf("get_dns: %s %s\n", buf, &buf[100]);
memset(buf, '\0', sizeof(buf));
}
makefile:
gcc main.c net_util.c -o get_net_info
./get_net_info
运行结果:
get_ipaddr: 192.168.9.142
get_mask: 255.255.255.0
get_gateway: 192.168.9.254
get_dns: 192.168.9.11 192.168.9.10
为提高执行效率, 更新获取网关和子网掩码程序:
static void get_gateway(const char *net_dev, char *gateway)
{
FILE *fp;
char buf[1024];
char iface[16];
unsigned char tmp[100]={'\0'};
unsigned int dest_addr=0, gate_addr=0;
if(NULL == gateway)
{
DEBUG_PRT("gateway is NULL \n");
return;
}
fp = fopen("/proc/net/route", "r");
if(fp == NULL){
DEBUG_PRT("fopen error \n");
return;
}
fgets(buf, sizeof(buf), fp);
while(fgets(buf, sizeof(buf), fp))
{
if((sscanf(buf, "%s\t%X\t%X", iface, &dest_addr, &gate_addr) == 3)
&& (memcmp(net_dev, iface, strlen(net_dev)) == 0)
&& gate_addr != 0)
{
memcpy(tmp, (unsigned char *)&gate_addr, 4);
sprintf(gateway, "%d.%d.%d.%d", (unsigned char)*tmp, (unsigned char)*(tmp+1), (unsigned char)*(tmp+2), (unsigned char)*(tmp+3));
break;
}
}
fclose(fp);
}
static void get_mask(const char *net_dev, ITI_CHAR *mask)
{
struct sockaddr_in *pAddr;
struct ifreq ifr;
int sockfd;
sockfd = socket(AF_INET,SOCK_DGRAM,0);
memset(&ifr,0,sizeof(ifr));
strcpy(ifr.ifr_name, net_dev);
if(ioctl(sockfd, SIOCGIFNETMASK, &ifr) < 0){
DEBUG_PRT("SIOCGIFADDR socket failed \n");
close(sockfd);
return ;
}
pAddr = (struct sockaddr_in *)&(ifr.ifr_addr);
strcpy(mask, (char *)(inet_ntoa(pAddr->sin_addr)));
close(sockfd);
}
========
Linux环境编程:获取网卡的实时网速
在Windows下面,我们可以看到360或者是qq安全卫士的“安全球”,上面显示实时的网速情况。那么在Linux里面如何获取网卡的实时网速?其实原理很简单,读取需要获取网速的网卡在某段时间dT内流量的变化dL,那么实时网速就出来了,Speed = dL / dt。
Linux在ifaddrs.h中提供了函数:
/* Create a linked list of `struct ifaddrs' structures, one for each
network interface on the host machine. If successful, store the
list in *IFAP and return 0. On errors, return -1 and set `errno'.
The storage returned in *IFAP is allocated dynamically and can
only be properly freed by passing it to `freeifaddrs'. */
extern int getifaddrs (struct ifaddrs **__ifap) __THROW;
/* Reclaim the storage allocated by a previous `getifaddrs' call. */
extern void freeifaddrs (struct ifaddrs *__ifa) __THROW;
系统会创建一个包含本机所有网卡信息链表,然后我们就可以在这个链表里面获取我们想要的信息。
/* The `getifaddrs' function generates a linked list of these structures.
Each element of the list describes one network interface. */
struct ifaddrs
{
struct ifaddrs *ifa_next; /* Pointer to the next structure. */
char *ifa_name; /* Name of this network interface. */
unsigned int ifa_flags; /* Flags as from SIOCGIFFLAGS ioctl. */
struct sockaddr *ifa_addr; /* Network address of this interface. */
struct sockaddr *ifa_netmask; /* Netmask of this interface. */
union
{
/* At most one of the following two is valid. If the IFF_BROADCAST
bit is set in `ifa_flags', then `ifa_broadaddr' is valid. If the
IFF_POINTOPOINT bit is set, then `ifa_dstaddr' is valid.
It is never the case that both these bits are set at once. */
struct sockaddr *ifu_broadaddr; /* Broadcast address of this interface. */
struct sockaddr *ifu_dstaddr; /* Point-to-point destination address. */
} ifa_ifu;
/* These very same macros are defined by <net/if.h> for `struct ifaddr'.
So if they are defined already, the existing definitions will be fine. */
# ifndef ifa_broadaddr
# define ifa_broadaddr ifa_ifu.ifu_broadaddr
# endif
# ifndef ifa_dstaddr
# define ifa_dstaddr ifa_ifu.ifu_dstaddr
# endif
void *ifa_data; /* Address-specific data (may be unused). */
};
另外这个链表我们是可以提前用ioctl来筛选的,可以通过ifa_name和ifa_flags来确定ifa_ifu里面到底选用那个union。不过这次我们是来测量实时网速的,不必要关心这个。
我们需要关心的是ifa_data这个项,关于这个项我百度了很多,一直没有发现他到底应该属于哪个结构体的。
后来无意在 http://www.linuxidc.com/Linux/2014-11/109289.htm 发现有类似的,但是我找不到头文件在那,所以后来干脆我直接把他放到我的头文件里面;
struct if_data{
/* generic interface information */
u_char ifi_type; /* ethernet, tokenring, etc */
u_char ifi_addrlen; /* media address length */
u_char ifi_hdrlen; /* media header length */
u_long ifi_mtu; /* maximum transmission unit */
u_long ifi_metric; /* routing metric (external only) */
u_long ifi_baudrate; /* linespeed */
/* volatile statistics */
u_long ifi_ipackets; /* packets received on interface */
u_long ifi_ierrors; /* input errors on interface */
u_long ifi_opackets; /* packets sent on interface */
u_long ifi_oerrors; /* output errors on interface */
u_long ifi_collisions; /* collisions on csma interfaces */
u_long ifi_ibytes; /* total number of octets received */
u_long ifi_obytes; /* total number of octets sent */
u_long ifi_imcasts; /* packets received via multicast */
u_long ifi_omcasts; /* packets sent via multicast */
u_long ifi_iqdrops; /* dropped on input, this interface */
u_long ifi_noproto; /* destined for unsupported protocol */
struct timeval ifi_lastchange;/* last updated */
};
刚刚开始我就打印了ifi_iobytes,ifi_obytes这两个项,不管我怎么下载和上次文件,这两个量都是0。纠结了我半天,我就直接把所有变量都打印出来,发现ifi_mtu,ifi_metric,ifi_baudrate跟ifconfig eth0输出的数据很像。
[15:12 @ ~/program/netspeed]$ ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:22:15:67:F8:16
inet addr:210.42.158.204 Bcast:210.42.158.255 Mask:255.255.255.0
inet6 addr: fe80::222:15ff:fe67:f816/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:917978 errors:0 dropped:0 overruns:0 frame:0
TX packets:1132894 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:132866544 (126.7 MiB) TX bytes:1250785627 (1.1 GiB)
Interrupt:29 Base address:0x4000
慢慢的我知道了规律,struct ifaddrs里面的ifa_data前四个字(32位)以此是发送数据包数,接收数据包数,发送字节数,接收字节数。
我就重新调整了struct if_data的结构体,由于后面的数据全为0,我就保留了4项:
struct if_data
{
/* generic interface information */
u_long ifi_opackets; /* packets sent on interface */
u_long ifi_ipackets; /* packets received on interface */
u_long ifi_obytes; /* total number of octets sent */
u_long ifi_ibytes; /* total number of octets received */
};
测试OK。
[15:17 @ ~/program/netspeed]$ ./netspeed
Get eth0 Speed [OK]
eth0: Up Speed: 1.671066 MB/s || Down Speed: 0.036335 MB/s
附上我已经封装好的代码:
int get_if_dbytes(struct if_info* ndev)
{
assert(ndev);
struct ifaddrs *ifa_list = NULL;
struct ifaddrs *ifa = NULL;
struct if_data *ifd = NULL;
int ret = 0;
ret = getifaddrs(&ifa_list);
if(ret < 0) {
perror("Get Interface Address Fail:");
goto end;
}
for(ifa=ifa_list; ifa; ifa=ifa->ifa_next){
if(!(ifa->ifa_flags & IFF_UP) && !(ifa->ifa_flags & IFF_RUNNING))
continue;
if(ifa->ifa_data == 0)
continue;
ret = strcmp(ifa->ifa_name,ndev->ifi_name);
if(ret == 0){
ifd = (struct if_data *)ifa->ifa_data;
ndev->ifi_ibytes = ifd->ifi_ibytes;
ndev->ifi_obytes = ifd->ifi_obytes;
break;
}
}
freeifaddrs(ifa_list);
end:
return (ret ? -1 : 0);
}
int get_if_speed(struct if_speed *ndev)
{
assert(ndev);
struct if_info *p1=NULL,*p2=NULL;
p1 = (struct if_info *)malloc(sizeof(struct if_info));
p2 = (struct if_info *)malloc(sizeof(struct if_info));
bzero(p1,sizeof(struct if_info));
bzero(p2,sizeof(struct if_info));
strncpy(p1->ifi_name,ndev->ifs_name,strlen(ndev->ifs_name));
strncpy(p2->ifi_name,ndev->ifs_name,strlen(ndev->ifs_name));
int ret = 0;
ret = get_if_dbytes(p1);
if(ret < 0) goto end;
usleep(ndev->ifs_us);
ret = get_if_dbytes(p2);
if(ret < 0) goto end;
ndev->ifs_ispeed = p2->ifi_ibytes - p1->ifi_ibytes;
ndev->ifs_ospeed = p2->ifi_obytes - p1->ifi_obytes;
end:
free(p1);
free(p2);
return 0;
}
头文件:
#ifndef __TSPEED_H__
#define __TSPEED_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <error.h>
/* For "open" function */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
struct if_data
{
/* generic interface information */
u_long ifi_opackets; /* packets sent on interface */
u_long ifi_ipackets; /* packets received on interface */
u_long ifi_obytes; /* total number of octets sent */
u_long ifi_ibytes; /* total number of octets received */
};
struct if_info
{
char ifi_name[16];
unsigned long ifi_ibytes;
unsigned long ifi_obytes;
};
struct if_speed
{
char ifs_name[16];
unsigned long ifs_ispeed;
unsigned long ifs_ospeed;
unsigned long ifs_us;
};
extern int get_if_dbytes(struct if_info *ndev);
extern int get_if_speed(struct if_speed *ndev);
#ifdef __cplusplus
}
#endif
#endif
测试代码:
int main (int argc, char **argv)
{
struct if_speed ndev;
int ret = 0;
bzero(&ndev,sizeof(ndev));
sprintf(ndev.ifs_name,"eth0");
ndev.ifs_us = 100000;
printf("Get %s Speed");
ret = get_if_speed(&ndev);
if(ret < 0)
printf("\t\t\t[Fail]\n");
else
printf("\t\t\t[OK]\n");
float ispeed ,ospeed;
while(1){
ispeed = ndev.ifs_ispeed * 1.0/(ndev.ifs_us/1000 * 0.001);
ospeed = ndev.ifs_ospeed * 1.0/(ndev.ifs_us/1000 * 0.001);
printf("%s: Up Speed: %f MB/s || Down Speed: %f MB/s \r",
ndev.ifs_name,ispeed/(1024.0*1024.0),ospeed/(1024.0*1024.0));
get_if_speed(&ndev);
}
return 0;
} /* ----- End of main() ----- */
可能你有更好的获取网速的办法,求留言指点!
========
相关链接
http://blog.youkuaiyun.com/taiyang1987912/article/details/46010923linux编程获取网络信息