您的位置:首页 > 理论基础 > 计算机网络

Linux编程获取网络信息总结

2016-03-19 22:13 811 查看

Linux下C获取所有可用网卡信息

在Linux下开发网络程序时,经常会遇到需要取本地网络接口名、IP、广播地址

、子网掩码或者MAC地址等信息的需求,最常见的办法是配合宏SIOCGIFHWADDR、

SIOCGIFADDR、SIOCGIFBRDADDR与SIOCGIFNETMASK作为参数调用

在Linux下开发网络程序时,经常会遇到需要取本地网络接口名、IP、广播地址

、子网掩码或者MAC地址等信息的需求,最常见的办法是配合宏SIOCGIFHWADDR、

SIOCGIFADDR、SIOCGIFBRDADDR与SIOCGIFNETMASK作为参数调用函数ioctl分别获

得MAC地址、IP地址、广播地址与子网掩码来实现。一次性获取此类信息的C语言

代码实现如下。 

海姹网(网址:http://www.seacha.com),标签:Linux下C获取所有可用网卡信

息, 网卡,ioctl,IP

#include <stdio.h>

#include <string.h>

#include <net/if.h>

#include <sys/ioctl.h>

#include <arpa/inet.h>

#include <errno.h>

int getLocalInfo(void)

{

    int fd;

    int interfaceNum = 0;

    struct ifreq buf[16];

    struct ifconf ifc;

    struct ifreq ifrcopy;

    char mac[16] = {0};

    char ip[32] = {0};

    char broadAddr[32] = {0};

    char subnetMask[32] = {0};

    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)

    {

        perror("socket");

        close(fd);

        return -1;

    }

    ifc.ifc_len = sizeof(buf);

    ifc.ifc_buf = (caddr_t)buf;

    if (!ioctl(fd, SIOCGIFCONF, (char *)&ifc))

    {

        interfaceNum = ifc.ifc_len / sizeof(struct ifreq);

        printf("interface num = %dn", interfaceNum);

        while (interfaceNum-- > 0)

        {

            printf("ndevice name: %sn", buf[interfaceNum].ifr_name);

            //ignore the interface that not up or not runing  

            ifrcopy = buf[interfaceNum];

            if (ioctl(fd, SIOCGIFFLAGS, &ifrcopy))

            {

                printf("ioctl: %s [%s:%d]n", strerror(errno), 

__FILE__, __LINE__);

                close(fd);

                return -1;

            }

            //get the mac of this interface  

            if (!ioctl(fd, SIOCGIFHWADDR, (char *)(&buf

[interfaceNum])))

            {

                memset(mac, 0, sizeof(mac));

                snprintf(mac, sizeof(mac), "%02x%02x%02x%02x%02x%02x",

                    (unsigned char)buf

[interfaceNum].ifr_hwaddr.sa_data[0],

                    (unsigned char)buf

[interfaceNum].ifr_hwaddr.sa_data[1],

                    (unsigned char)buf

[interfaceNum].ifr_hwaddr.sa_data[2],

                    (unsigned char)buf

[interfaceNum].ifr_hwaddr.sa_data[3],

                    (unsigned char)buf

[interfaceNum].ifr_hwaddr.sa_data[4],

                    (unsigned char)buf

[interfaceNum].ifr_hwaddr.sa_data[5]);

                printf("device mac: %sn", mac);

            }

            else

            {

                printf("ioctl: %s [%s:%d]n", strerror(errno), 

__FILE__, __LINE__);

                close(fd);

                return -1;

            }

            //get the IP of this interface  

            if (!ioctl(fd, SIOCGIFADDR, (char *)&buf[interfaceNum]))

            {

                snprintf(ip, sizeof(ip), "%s",

                    (char *)inet_ntoa(((struct sockaddr_in *)&(buf

[interfaceNum].ifr_addr))->sin_addr));

                printf("device ip: %sn", ip);

            }

            else

            {

                printf("ioctl: %s [%s:%d]n", strerror(errno), 

__FILE__, __LINE__);

                close(fd);

                return -1;

            }

            //get the broad address of this interface  

            if (!ioctl(fd, SIOCGIFBRDADDR, &buf[interfaceNum]))

            {

                snprintf(broadAddr, sizeof(broadAddr), "%s",

                    (char *)inet_ntoa(((struct sockaddr_in *)&(buf

[interfaceNum].ifr_broadaddr))->sin_addr));

                printf("device broadAddr: %sn", broadAddr);

            }

            else

            {

                printf("ioctl: %s [%s:%d]n", strerror(errno), 

__FILE__, __LINE__);

                close(fd);

                return -1;

            }

            //get the subnet mask of this interface  

            if (!ioctl(fd, SIOCGIFNETMASK, &buf[interfaceNum]))

            {

                snprintf(subnetMask, sizeof(subnetMask), "%s",

                    (char *)inet_ntoa(((struct sockaddr_in *)&(buf

[interfaceNum].ifr_netmask))->sin_addr));

                printf("device subnetMask: %sn", subnetMask);

            }

            else

            {

                printf("ioctl: %s [%s:%d]n", strerror(errno), 

__FILE__, __LINE__);

                close(fd);

                return -1;

            }

        }

    }

    else

    {

        printf("ioctl: %s [%s:%d]n", strerror(errno), __FILE__, 

__LINE__);

        close(fd);

        return -1;

    }

  

    close(fd);

    return 0;

}

  

int main(void)

{

    getLocalInfo();

    return 0;

}

使用ioctl函数虽然可以获取所有的信息,但是使用起来比较麻烦,如果不需要

获取MAC地址,那么使用getifaddrs函数来获取更加方便与简洁。值得一提的是

,在MacOS或iOS系统上(如iPhone程序开发),上述iotcl函数没法获得mac地址

跟子网掩码,这个使用,使用getifaddrs函数便更有优势了。下面是使用

getiaddrs函数获取网卡信息的C语言代码实现。

#include <stdio.h>  

#include <ifaddrs.h>  

#include <arpa/inet.h>  

  

int getSubnetMask()

{

    struct sockaddr_in *sin = NULL;

    struct ifaddrs *ifa = NULL, *ifList;

    if (getifaddrs(&ifList) < 0)

    {

        return -1;

    }

    for (ifa = ifList; ifa != NULL; ifa = ifa->ifa_next)

    {

        if(ifa->ifa_addr->sa_family == AF_INET)

        {

            printf("n>>> interfaceName: %sn", ifa->ifa_name);

            sin = (struct sockaddr_in *)ifa->ifa_addr;

            printf(">>> ipAddress: %sn", inet_ntoa(sin->sin_addr));

            sin = (struct sockaddr_in *)ifa->ifa_dstaddr;

            printf(">>> broadcast: %sn", inet_ntoa(sin->sin_addr));

            sin = (struct sockaddr_in *)ifa->ifa_netmask;

            printf(">>> subnetMask: %sn", inet_ntoa(sin->sin_addr));

        }

    }

    freeifaddrs(ifList);

    return 0;

}

  

int main(void)

{

    getSubnetMask();

    return 0;

}

========

linux下获取主机IP地址的源码

支持多网卡,主要是使用ioctl函数系统调用实现,通过指定设备名实现指定功能.

之前使用socket()函数,获取文件描述符.在此基础可以很轻松的扩展,如获取net 

mask,MAC address等 #include stdio.h #include sys/types.

      支持多网卡,主要是使用ioctl函数系统调用实现,通过指定设备名实现指

定功能.之前使用socket()函数,获取文件描述符.在此基础可以很轻松的扩展,如

获取net mask,MAC address等

      

      #include <stdio.h>

      #include <sys/types.h>

      #include <sys/param.h>

      

      #include <sys/ioctl.h>

      #include <sys/socket.h>

      #include <net/if.h>

      #include <netinet/in.h>

      #include <net/if_arp.h>

      

      #define MAXINTERFACES 16 

      int main(void)

      {

        register int fd, intrface;

        struct ifreq buf[MAXINTERFACES];

        struct ifconf ifc;

        if ((fd = socket (AF_INET, SOCK_DGRAM, 0)) < 0)

        {

          return -1;

        } 

        ifc.ifc_len = sizeof(buf); 

        ifc.ifc_buf = (caddr_t) buf;

        if (ioctl (fd, SIOCGIFCONF, (char *) &ifc) < 0) 

        { 

          return -1; 

        }

        intrface = ifc.ifc_len / sizeof (struct ifreq); 

        printf("number of interface is: %d\n",intrface); 

        while (intrface-- > 0) 

        { 

          printf ("net device %s\n", buf[intrface].ifr_name); 

          if ((ioctl (fd, SIOCGIFFLAGS, (char *) &buf[intrface])) < 0)

          {

            continue; 

          } 

          if (buf[intrface].ifr_flags & IFF_PROMISC)

          { 

            puts ("the interface is PROMISC"); 

          } 

          else 

          {

            if (buf[intrface].ifr_flags & IFF_UP) 

            {

              puts("the interface status is UP"); 

            }

            else

            {

              if (buf[intrface].ifr_flags & IFF_RUNNING)

                puts("the interface status is RUNNING");

            }

          }

       

          if (!(ioctl (fd, SIOCGIFADDR, (char *) &buf[intrface]))) 

          {

            puts ("IP address is:"); 

            puts(inet_ntoa(((struct sockaddr_in*)(&buf

[intrface].ifr_addr))->sin_addr));

            puts(""); 

          } 

          else

          { 

            char str[256]; 

            sprintf (str, "cpm: ioctl device %s", buf

[intrface].ifr_name); perror (str);

          }

        }

        close (fd); 

        return 0; 

      }

========

linux 系统获取网络ip, mask, gateway, dns信息小程序

net_util.c

       #define WIRED_DEV                   "eth0" 

    #define WIRELESS_DEV                "ra0"           

    #define PPPOE_DEV                   "ppp0"

#define DEBUG_PRT(fmt, arg...)      printf(fmt,##arg)

/**

 * get ip address.

 * @param net_dev net device.

 * @param ipaddr a pointer to save ip address.

 * @return 0 success, or fail.

 */

int get_ipaddr(const char *net_dev,  char *ipaddr)

{

    struct ifreq ifr;

    int fd = 0;

    struct sockaddr_in *pAddr;

    if((NULL == net_dev) || (NULL == ipaddr))

    {

        DEBUG_PRT("illegal call function SetGeneralIP! \n");

        return -1;

    }

    if((fd = socket(AF_INET,SOCK_DGRAM,0)) < 0)

    {

        DEBUG_PRT("open socket failed \n");

        return -1;

    }

    memset(&ifr,0,sizeof(ifr));

    strcpy(ifr.ifr_name, net_dev);

    if(ioctl(fd, SIOCGIFADDR, &ifr) < 0)

    {

        DEBUG_PRT("SIOCGIFADDR socket failed \n");

        close(fd);

        return -1;

    }

    pAddr = (struct sockaddr_in *)&(ifr.ifr_addr);

    strcpy(ipaddr, inet_ntoa(pAddr->sin_addr));

    

    close(fd);

    

    return 0;

}

/**

 * get gateway.

 * @param gateway a pointer to save geteway.

 * @return none.

 */

void get_gateway(ITI_CHAR *gateway)

{

    char buf[1024]={0};

    char *p = NULL;

    char *q = NULL;

    int count = 0;

    if(NULL == gateway)

    {

        DEBUG_PRT("gateway is NULL \n");

        return; 

    }

    cmd_run("route | grep default", buf, 1024);

    if(0 == strlen(buf))

    {

        DEBUG_PRT("get gateway error \n");

        return;

    }

    p = strstr2(buf, "default");

    q = p;

    while(*q == ' ')

    {

        q++;

    }

    p = q;

    while(*p != ' ')

    {

        p++;

        count++;

    }

    if(NULL != q)

    {

        memcpy(gateway, q, count);

    }

    gateway[count] = '\0';  

}

/**

 * get mask.

 * @param net_dev net device.

 * @param mask a pointer to save mask.

 * @return none.

 */

void get_mask(const char *net_dev, ITI_CHAR *mask)

{

    char buf[1024]={0};

    char *p = NULL;

    if(NULL == mask)

    {

        DEBUG_PRT("mask is NULL \n");

        return; 

    }

    if(0 == (memcmp(WIRED_DEV, net_dev, sizeof(WIRED_DEV))))

    {

        cmd_run("ifconfig eth0 | grep Mask", buf, 1024);

    }

    else if(0 == (memcmp(WIRELESS_DEV, net_dev, sizeof(WIRELESS_DEV))))

    {

        cmd_run("ifconfig ra0 | grep Mask", buf, 1024);

    }

    else if(0 == (memcmp(PPPOE_DEV, net_dev, sizeof(PPPOE_DEV))))

    {

        cmd_run("ifconfig ppp0 | grep Mask", buf, 1024);

    }

    else 

    {

        DEBUG_PRT("net device not support \n");

        return; 

    }

    

    if(0 == strlen(buf))

    {

        DEBUG_PRT("get mask error \n");

        return;

    }

    p = strstr2(buf, "Mask:");

    if(NULL == p)

    {

        DEBUG_PRT("get mask error \n");

        return;

    }

    strcpy(mask, p);

}

/**

 * get dns.

 * @param dns1 a pointer to save first dns.

 * @param dns2 a pointer to save second dns.

 * @return 0 success, or fail.

 */

int get_dns(char *dns1, char *dns2)

{

    int fd = -1;

    int size = 0;

    char strBuf[100];

    char tmpBuf[100];

    int buf_size = sizeof(strBuf);

    char *p = NULL;

    char *q = NULL;

    int i = 0;

    int j = 0;

    int count = 0;

    

    fd = open("/etc/resolv.conf", O_RDONLY);

    if(-1 == fd)

    {

        DEBUG_PRT("%s open error \n", __func__);

        return -1;

    }

    size = read(fd, strBuf, buf_size);

    if(size < 0)

    {

        DEBUG_PRT("%s read file len error \n", __func__);

        close(fd);

        return -1;

    }

    strBuf[buf_size] = '\0';

    close(fd);

    while(i < buf_size)

    {

        if((p = strstr2(&strBuf[i], "nameserver")) != NULL)

        {

            j++;

            p += 1;

            count = 0;

            

            memset(tmpBuf, 0xff, 100);

            memcpy(tmpBuf, p, 100);

            tmpBuf[sizeof(tmpBuf) -1 ] = '\0';

            

            q = p;

            while(*q != '\n')

            {

                q++;

                count++;

            }

            i += (sizeof("nameserver") + count);

            

            if(1 == j)

            {

                memcpy(dns1, p, count);

                dns1[count]='\0';

            }

            else if(2 == j)

            {

                memcpy(dns2, p, count);

                dns2[count]='\0';

            }

        } 

        else 

        {

            i++;

        }

    }

    return 0;

}

main.c

void main(void)

{

        #define WIRED_DEV                   "eth0" 

    #define WIRELESS_DEV                "ra0"           

    #define PPPOE_DEV                   "ppp0"

        char buf[1024] = {'\0'};

    extern int get_ipaddr(const char *net_dev,  char *ipaddr);

    get_ipaddr(WIRED_DEV, buf);

    printf("get_ipaddr: %s \n", buf);

    memset(buf, '\0', sizeof(buf));

    

    extern void get_mask(const char *net_dev, ITI_CHAR *mask);

    get_mask(WIRED_DEV, buf);

    printf("get_mask: %s \n", buf);

    memset(buf, '\0', sizeof(buf));

    

    extern void get_gateway(ITI_CHAR *gateway);

    get_gateway(buf);

    printf("get_gateway: %s \n", buf);

    memset(buf, '\0', sizeof(buf));

    extern int get_dns(char *dns1, char *dns2);

    get_dns(buf, &buf[100]);

    printf("get_dns: %s %s\n", buf, &buf[100]);

    memset(buf, '\0', sizeof(buf));

}

makefile:

gcc main.c net_util.c -o get_net_info

./get_net_info

运行结果:

get_ipaddr: 192.168.9.142 

get_mask: 255.255.255.0

get_gateway: 192.168.9.254 

get_dns: 192.168.9.11 192.168.9.10

为提高执行效率, 更新获取网关和子网掩码程序:

static void get_gateway(const char *net_dev, char *gateway)

{

    FILE *fp;    

    char buf[1024];  

    char iface[16];    

    unsigned char tmp[100]={'\0'};

    unsigned int dest_addr=0, gate_addr=0;

    if(NULL == gateway)

    {

        DEBUG_PRT("gateway is NULL \n");

        return; 

    }

    fp = fopen("/proc/net/route", "r");    

    if(fp == NULL){  

        DEBUG_PRT("fopen error \n");

        return;   

    }

    

    fgets(buf, sizeof(buf), fp);    

    while(fgets(buf, sizeof(buf), fp)) 

    {    

        if((sscanf(buf, "%s\t%X\t%X", iface, &dest_addr, &gate_addr) == 3) 

            && (memcmp(net_dev, iface, strlen(net_dev)) == 0)

            && gate_addr != 0) 

        {

                memcpy(tmp, (unsigned char *)&gate_addr, 4);

                sprintf(gateway, "%d.%d.%d.%d", (unsigned char)*tmp, (unsigned char)*(tmp+1), (unsigned char)*(tmp+2), (unsigned char)*(tmp+3));

                break;    

        }

    }    

      

    fclose(fp);

}

static void get_mask(const char *net_dev, ITI_CHAR *mask)

{

    struct sockaddr_in *pAddr;

    struct ifreq ifr;

    int sockfd;

    sockfd = socket(AF_INET,SOCK_DGRAM,0);

    memset(&ifr,0,sizeof(ifr));

    strcpy(ifr.ifr_name, net_dev);

    

    if(ioctl(sockfd, SIOCGIFNETMASK, &ifr) < 0){

        DEBUG_PRT("SIOCGIFADDR socket failed \n");

        close(sockfd);

        return ;

    }

    pAddr = (struct sockaddr_in *)&(ifr.ifr_addr);

    strcpy(mask, (char *)(inet_ntoa(pAddr->sin_addr)));

    

    close(sockfd);

}

========

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

 

在Windows下面,我们可以看到360或者是qq安全卫士的“安全球”,上面显示实时的网速情况。那么在Linux里面如何获取网卡的实时网速?其实原理很简单,读取需要获取网速的网卡在某段时间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://www.linuxidc.com/Linux/2014-11/109289.htm 发现有类似的,但是我找不到头文件在那,所以后来干脆我直接把他放到我的头文件里面;

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() ----- */

可能你有更好的获取网速的办法,求留言指点!

========

相关链接

http://blog.csdn.net/taiyang1987912/article/details/46010923

linux编程获取网络信息
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息