在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环境编程】获取网卡的实时网速的更多相关文章

  1. Linux环境编程相关的文章

    Linux环境编程相关的文章 好几年没有接触Linux环境下编程了,好多东西都有点生疏了.趁着现在有空打算把相关的一些技能重拾一下,顺手写一些相关的文章加深印象. 因为不是写书,也受到许多外部因素限制 ...

  2. TrafficStats——流量统计类的范例,获取实时网速

    2.3开始android就提供来这个类的API,这样我们就可以方便的用他来实现统计手机流量来.这个类其实也很简单,我贴上他的几个方法,大家一看就知道怎么用了. static long getMobil ...

  3. proc/net/dev实时网速统计实例【转】

    转自:https://blog.csdn.net/dosthing/article/details/80384541 前言 网络编程是程序连接网络拓展的基础,尤其是在物联网.互联网加等概念火热的当下, ...

  4. C# 实现实时网速

    前言 最近参加了一个项目,所以写博客的时间就少了,项目中有一个功能就是在窗体上显示实时网速,用了半天的时间写了出来,想想今天时间蛮充足,就把它分享到博客上吧. 项目展示 项目核心代码: private ...

  5. Linux下编程获取本地IP地址的常见方法

    转载于:http://blog.csdn.net/k346k346/article/details/48231933 在进行linux网络编程时,经常用到本机IP地址.本文罗列一下常见方法,以备不时之 ...

  6. Linux 环境编程:dirfd参数 有关解析

    背景 在Unix环境编程中,系统提供了很多以at结尾的函数,如openat.fstatat等,而这类函数通常有一个特点,就是形参列表中多了int dirfd 例如: int open(const ch ...

  7. Android中获取实时网速(2)

    一.实现思路: 1.Android提供有获取当前总流量的方法 2.上一秒 减去 下一面的流量差便是网速 3.注意计算 二.计算网速的工具类: package imcs.cb.com.viewappli ...

  8. python检测当前网卡流量信息,用于查看实时网速

    可以用来检测是否有挖矿程序在运行的一个子条件 # coding:utf-8 __author__ = 'chenhuachao' import wmi import time import platf ...

  9. Linux命令(20)查看当前网速

    Linux查看网络即时网速 sar -n DEV 1 100 1代表一秒统计并显示一次 100代表统计一百次 还可以使用ntop工具

随机推荐

  1. Canvas中的非零围绕规则原理

    非零围绕规则:对于路径中指定范围区域,从该区域内部画一条足够长的线段.使此线段的全然落在路径范围之外. 非零围绕规则计数器:然后,将计数器初始化为0,每当这个线段与路径上的直线或曲线相交时,就改变计数 ...

  2. linux 抓包 tcpdump 简单应用

    在linuxserver上,常常要定位网络问题,就须要用到抓包. 比如:tcpdump -X -s 0 host 10.17.81.22 and port 9999 -w /home/text.cap ...

  3. java关键字之transient

    转自:http://www.cnblogs.com/lanxuezaipiao/p/3369962.html 1. transient的作用及使用方法 我们都知道一个对象只要实现了Serilizabl ...

  4. angularjs 遍历

    <!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...

  5. Oracle数据库Helper类

    using System;using System.Collections.Generic;using System.Data;using System.Data.OleDb;using System ...

  6. Spring深入浅出(一)IOC的基本知识

    Spring前言 Spring是一个企业级开发框架,为解决企业级项目开发过于复杂而创建的,框架的主要优势之一就是分层架构,允许开发者自主选择组件. Spring的两大核心机制是IOC(控制反转)和AO ...

  7. 关于md解析器

    不得不说,博客园的 md 解析器真的不够好.和 csdn 以及 sf 社区的比起来,差太多了.以后,博客园就老老实实写随笔了,文章类的还是用 csdn 吧.

  8. PostgreSQL Replication之第九章 与pgpool一起工作(4)

    9.4 设置复制和负载均衡 要配置pgpool,我们可以简单地使用一个包含一种典型的配置信息的已经存在的样本文件,将它拷贝到我们的配置目录并修改之: $ cp /usr/local/etc/pgpoo ...

  9. 将double数据保留两位小数

    private double formatDouble(double number) { DecimalFormat df = new DecimalFormat("#.00"); ...

  10. 删除小脚本 srm

    提示:只能删除当前路径下的目录或文件 #!/bin/bash #将测试好的脚本,拷贝到 $PATH 能够搜索到目录下.并且改名 例如: /usr/local/bin cp /test/srm.sh / ...