linux中查看网卡信息_目前公认最流畅的linux[通俗易懂]

linux中查看网卡信息_目前公认最流畅的linux[通俗易懂]在Windows下面,我们可以看到360或者是qq安全卫士的“安全球”,上面显示实时的网速情况

在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 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这个项,关于这个项我百度了很多,一直没有发现他到底应该属于哪个结构体的。

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

#include

#include

#include

#include

/* For “open” function */

#include

#include

#include

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() —– */

可能你有更好的获取网速的办法,求留言指点!

0b1331709591d260c1c78e86d0c51c18.png

今天的文章linux中查看网卡信息_目前公认最流畅的linux[通俗易懂]分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/83700.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注