Linux编程获取网络信息总结

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编程获取网络信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值