【Linux环境编程】获取网卡的实时网速
在windows以下。我们能够看到360或者是qq安全卫士的“安全球”。上面显示实时的网速情况。那么在linux里面怎样获取网卡的实时网速?事实上原理非常easy,读取须要获取网速的网卡在某段时间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://blog.chinaunix.net/uid-22832715-id-292763.html发现有相似的,可是我找不到头文件在那。所以后来干脆我直接把他放到我的头文件中面;
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() ----- */
可能你有更好的获取网速的办法,求留言指点!
【Linux环境编程】获取网卡的实时网速的更多相关文章
- Linux环境编程相关的文章
Linux环境编程相关的文章 好几年没有接触Linux环境下编程了,好多东西都有点生疏了.趁着现在有空打算把相关的一些技能重拾一下,顺手写一些相关的文章加深印象. 因为不是写书,也受到许多外部因素限制 ...
- TrafficStats——流量统计类的范例,获取实时网速
2.3开始android就提供来这个类的API,这样我们就可以方便的用他来实现统计手机流量来.这个类其实也很简单,我贴上他的几个方法,大家一看就知道怎么用了. static long getMobil ...
- proc/net/dev实时网速统计实例【转】
转自:https://blog.csdn.net/dosthing/article/details/80384541 前言 网络编程是程序连接网络拓展的基础,尤其是在物联网.互联网加等概念火热的当下, ...
- C# 实现实时网速
前言 最近参加了一个项目,所以写博客的时间就少了,项目中有一个功能就是在窗体上显示实时网速,用了半天的时间写了出来,想想今天时间蛮充足,就把它分享到博客上吧. 项目展示 项目核心代码: private ...
- Linux下编程获取本地IP地址的常见方法
转载于:http://blog.csdn.net/k346k346/article/details/48231933 在进行linux网络编程时,经常用到本机IP地址.本文罗列一下常见方法,以备不时之 ...
- Linux 环境编程:dirfd参数 有关解析
背景 在Unix环境编程中,系统提供了很多以at结尾的函数,如openat.fstatat等,而这类函数通常有一个特点,就是形参列表中多了int dirfd 例如: int open(const ch ...
- Android中获取实时网速(2)
一.实现思路: 1.Android提供有获取当前总流量的方法 2.上一秒 减去 下一面的流量差便是网速 3.注意计算 二.计算网速的工具类: package imcs.cb.com.viewappli ...
- python检测当前网卡流量信息,用于查看实时网速
可以用来检测是否有挖矿程序在运行的一个子条件 # coding:utf-8 __author__ = 'chenhuachao' import wmi import time import platf ...
- Linux命令(20)查看当前网速
Linux查看网络即时网速 sar -n DEV 1 100 1代表一秒统计并显示一次 100代表统计一百次 还可以使用ntop工具
随机推荐
- HDU 1542 Atlantis(矩形面积并)
HDU 1542 Atlantis 题目链接 题意:给定一些矩形,求面积并 思路:利用扫描线,因为这题矩形个数不多,直接暴力扫就能够了.假设数据大.就要用线段树 代码: #include <cs ...
- 几种常见sqlalchemy查询:
#简单查询 print(session.query(User).all()) print(session.query(User.name, User.fullname).all ...
- PHP join() 函数
PHP join() 函数 实例 把数组元素组合为一个字符串: <?php $arr = array('Hello','World!','I','love','Shanghai!'); echo ...
- Android 如何打造Android自定义的下拉列表框控件
一.概述 Android中的有个原生的下拉列表控件Spinner,但是这个控件有时候不符合我们自己的要求, 比如有时候我们需要类似windows 或者web网页中常见的那种下拉列表控件,类似下图这样的 ...
- PostgreSQL Replication之第三章 理解即时恢复(1)
到现在为止,您已经掌握了一定的理论.因为生活不仅由理论组成(它可能同样重要),是时候深入实际的工作了. 本章的目标是让您明白如何恢复数据到一个给定的时间点.当您的系统崩溃或者有人意外地删除了一个表,不 ...
- codeforces 401 B Sereja and Contests【贪心】
题意:给出最后的时间n,div 1必须和div2一起举行,并且div2的时间总是比div1大1 给出Sereja(只能参加div2)参加过的k场比赛的时间,问他最少错过了多少场div2,最多错过了多少 ...
- pip源
阿里云 http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/ 豆瓣(do ...
- tensorboard 使用
TensorBoard是TensorFlow 的可视化工具.主要为了更方便用户理解 TensorFlow 程序.调试与优化,用户可以用 TensorBoard 来展现 TensorFlow 图像,绘制 ...
- 洛谷 P1368 工艺 后缀自动机 求最小表示
后缀自动机沙茶题 将字符串复制一次,建立后缀自动机. 在后缀自动机上贪心走 $n$ 次即可. Code: #include <cstdio> #include <algorithm& ...
- caioj 1083 动态规划入门(非常规DP7:零件分组)(LIS)
这道题题目给的顺序不是固定的 所以一开始要自己排序,按照w来排序 后来只要看l就可以了 然后求最长下降子序列即可(根据那个神奇的定理,LIS模板里有提到) #include<cstdio> ...