转自:https://blog.csdn.net/dosthing/article/details/80384541
前言
网络编程是程序连接网络拓展的基础,尤其是在物联网、互联网加等概念火热的当下,网络编程能力体现了一个程序员能否具有大型程序的开发能力。在实际应用中,往往需要显示目前系统的实时网速等信息,当然获取网速等信息的软件方法很多,但是用小几行代码,并可移植性好的方法却不多,这里介绍如何通过Linux的proc文件系统进行实时获取网卡收发速率。
原理简介
Linux提供的LKM机制可以使我们通过proc伪文件系统来获取Linux内核信息,而通过proc/net/dev我们可以实时获取网络适配器及统计信息。抛开复杂的概念,简单说就是我们可以利用proc/net/dev来获取网卡的网速及网络包的收发情况。这里我们主要关心Receive和Transmit项的bytes项。bytes定义:The total number of bytes of datatransmitted or received by the interface. 即网口的发送或接收的数据的总字节数。更多选项的定义,我们用不着,如有兴趣了解戳这里。
实例详解
有了以上的背景知识,足够我们理解实例的内容了,直接上源码,看看如何实现实时统计网卡的网速信息。
#include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <sys/wait.h> #include <sys/time.h> #include <arpa/inet.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #include <dirent.h> #include <time.h> #include <fcntl.h> #include <errno.h> #ifdef debugprintf #define debugpri(mesg, args...) fprintf(stderr, "[NetRate print:%s:%d:] " mesg "\n", __FILE__, __LINE__, ##args) #else #define debugpri(mesg, args...) #endif int GetNetRate(FILE* fd,char *interface,long *recv,long *send) { char buf[1024]; char *p; char flow[32]; int i = 0; char tempstr[16][16]={0}; memset(buf,0,sizeof(buf)); memset(tempstr,0,sizeof(tempstr)); fseek(fd, 0, SEEK_SET); int nBytes = fread(buf,1, sizeof(buf)-1,fd); if (-1 == nBytes) { debugpri("fread error"); fclose(fd); return -1; } buf[nBytes] = '\0'; char* pDev = strstr(buf, interface); if (NULL == pDev) { printf("don't find dev %s\n", interface); fclose(fd); return -1; } sscanf(pDev,"%[^' ']\t%[^' ']\t%[^' ']\t%[^' ']\t%[^' ']\t%[^' ']\t%[^' ']\t%[^' ']\t%[^' ']\t%[^' ']\t%[^' ']\t%[^' ']\t",\ tempstr[0],tempstr[1],tempstr[2],tempstr[3],tempstr[4],tempstr[5],tempstr[6],tempstr[7],tempstr[8],tempstr[9],tempstr[10],tempstr[11]); *recv = atol(tempstr[1]); *send = atol(tempstr[9]); } int main(int argc, char** argv) { struct timeval tv_now,tv_pre; char netdevice[16]={0}; int nDevLen; long recvpre = 0,recvcur = 0; long sendpre = 0,sendcur = 0; double sendrate; double recvrate; if(argc != 2) { printf("Usage: netrate <network device>\n"); exit(0); } nDevLen = strlen(argv[1]); if (nDevLen < 1 || nDevLen > 10) { printf("unkown device\n"); exit(0); } sprintf(netdevice,"%s",argv[1]); FILE* fd = fopen("/proc/net/dev","r+"); if (NULL == fd) { debugpri("/proc/net/dev not exists!\n"); return -1; } while(1) { gettimeofday(&tv_pre,NULL); GetNetRate(fd,netdevice,&recvpre,&sendpre); sleep(2); gettimeofday(&tv_now,NULL); GetNetRate(fd,netdevice,&recvcur,&sendcur); recvrate= (recvcur - recvpre)/(1024*(tv_now.tv_sec+tv_now.tv_usec*0.000001-tv_pre.tv_sec+tv_pre.tv_usec*0.000001)); if(recvrate<0) { recvrate = 0; } sendrate= (sendcur - sendpre)/(1024*(tv_now.tv_sec+tv_now.tv_usec*0.000001-tv_pre.tv_sec+tv_pre.tv_usec*0.000001)); if(sendrate<0) { sendrate = 0; } system("clear"); printf("NetWorkRate Statistic Verson 0.0.1\n"); printf("Net Device receive rate send rate\n"); printf("%-10s\t%-6.2fKB/sec\t%-6.2fKB/sec\n",netdevice,recvrate,recvrate); } fclose(fd); return 0; }
总结:
物联网、互联网加的蓬勃发展,产品的功能实现越来越依赖网络,掌握一些网络编程的小技巧,可以使得我们在产品开发中能够事半功倍,提升软实力。今天是5月20日,在特殊的日子里整理一下知识,以做备忘,原创不易,转载说明文章出处。番外篇,我把上面的实例程序整理成了一个网络小工具,很实用,在主流的Linux平台编译运行没有任何的warning警告,如需要嵌入式移植开发或者其他用途请点此下载。