cat /proc/net/dev
Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构、改变内核设置的机制。proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取proc文件时,proc文件系统是动态从系统内核读出所需信息并提交的。
/proc文件系统中包含了很多目录,其中/proc/net/dev就是提供给用户读取或更改网络适配器及统计信息的途径。
注意:因为proc是伪文件系统,只存在内存中,所以这里统计的数据的时间起止时间是:系统启动到命令执行,如果此时系统发生重启,数据将会清零。
参数说明:
bytes: 接口发送或接收的数据的总字节数
packets: 接口发送或接收的数据包总数
errs: 由设备驱动程序检测到的发送或接收错误的总数
drop: 设备驱动程序丢弃的数据包总数
fifo: FIFO缓冲区错误的数量
frame: 分组帧错误的数量
colls: 接口上检测到的冲突数
compressed: 设备驱动程序发送或接收的压缩数据包数
carrier: 由设备驱动程序检测到的载波损耗的数量
multicast: 设备驱动程序发送或接收的多播帧数
其实,我们平时经常用的很多查看网卡实时流量的命令,都是通过读取该目录下的实时流量,并通过简单计算得到的。
#include#include #include #include #include #include // 更改为你要监测的网卡名称,可以通过ifconfig获得 #define INTERFACE_NAME "ens33" unsigned long long ticBytes; unsigned long long tocBytes; // 读取指定网卡的统计信息 int readInterfaceStats(const char *interfaceName, bool isTic) { FILE *file = fopen("/proc/net/dev", "r"); if (file == NULL) { printf("Failed to open /proc/net/dev"); return -1; } char line[256]; while (fgets(line, sizeof(line), file)) { if (strstr(line, interfaceName) != NULL) { if (isTic) { // 读取bytes的相关信息,用%*s跳过无用字符串 sscanf(line, "%*s %llu", &ticBytes); } else { sscanf(line, "%*s %llu", &tocBytes); } fclose(file); return 0; } } fclose(file); return -1; } long *myIfconfig(char *interfaceName) { int fd = open("/proc/net/dev", O_RDONLY | O_EXCL); if (-1 == fd) { printf("/proc/net/dev not exists!\n"); return NULL; } char buf[1024*2]; lseek(fd, 0, SEEK_SET); int nBytes = read(fd, buf, sizeof(buf)-1); if (-1 == nBytes) { printf("read error"); close(fd); return NULL; } buf[nBytes] = '\0'; close(fd); //返回第一次指向netCard位置的指针 char* pDev = strstr(buf, interfaceName); if (NULL == pDev) { printf("don't find dev %s\n", interfaceName); return NULL; } char *p; char *ifconfigValue; int i = 0; static long rx2Tx10[2]; /*去除空格,制表符,换行符等不需要的字段*/ for (p = strtok(pDev, " \t\r\n"); p; p = strtok(NULL, " \t\r\n")) { i++; ifconfigValue = (char*)malloc(20); strcpy(ifconfigValue, p); /*得到的字符串中的第二个字段是接收流量*/ if(i == 2) { rx2Tx10[0] = atol(ifconfigValue); } /*得到的字符串中的第十个字段是发送流量*/ if(i == 10) { rx2Tx10[1] = atol(ifconfigValue); break; } free(ifconfigValue); } return rx2Tx10; } int main() { double interval = 1.0; // 采样间隔,单位为秒 while (1) { if (readInterfaceStats(INTERFACE_NAME, true) == -1) { printf("Failed to read interface stats\n"); return -1; } sleep((unsigned int)interval); if (readInterfaceStats(INTERFACE_NAME, false) == -1) { printf("Failed to read interface stats\n"); return -1; } double kbps = (tocBytes - ticBytes) / interval / 1024; printf("receive speed is Kb/s: %.2f\n", kbps); long *ifconfigResult; double reKb; ifconfigResult = myIfconfig(INTERFACE_NAME); reKb = (double)ifconfigResult[0] / (1024); printf("Receive total: %0.2f KB\n", reKb); reKb = (double)ifconfigResult[1] / (1024); printf("Send total: %0.2f KB\n", reKb); } return 0; }
上一篇:黑客技术(网络安全)自学1.0