Linux环境编程:获取网卡的实时网速(2)

[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;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/5559c2cd249e14d723739add823d2e93.html