机器多个网卡或者绑定多个ip时,
获取机器IP信息:
ifaddrs的结构如下
   1: struct ifaddrs   
   2: {   
   3:     struct ifaddrs  *ifa_next;    /* Next item in list */   
   4:     char            *ifa_name;    /* Name of interface */   
   5:     unsigned int     ifa_flags;   /* Flags from SIOCGIFFLAGS */   
   6:     struct sockaddr *ifa_addr;    /* Address of interface */   
   7:     struct sockaddr *ifa_netmask; /* Netmask of interface */   
   8:     union   
   9:     {   
  10:         struct sockaddr *ifu_broadaddr; /* Broadcast address of interface */   
  11:         struct sockaddr *ifu_dstaddr; /* Point-to-point destination address */   
  12:     } ifa_ifu;   
  13:     #define              ifa_broadaddr ifa_ifu.ifu_broadaddr   
  14:     #define              ifa_dstaddr   ifa_ifu.ifu_dstaddr   
  15:     void            *ifa_data;    /* Address-specific data */   
  16: };   

ifa_next指向链表的下一个成员;ifa_name是接口名称,以0结尾的字符串,比如eth0,lo;ifa_flags是接口的标识位(比如当IFF_BROADCAST或IFF_POINTOPOINT设置到此标识位时,影响联合体变量ifu_broadaddr存储广播地址或ifu_dstaddr记录点对点地址);ifa_netmask存储该接口的子网掩码;结构体变量存储广播地址或点对点地址(见括弧介绍ifa_flags);ifa_data存储了该接口协议族的特殊信息,它通常是NULL(一般不关注他)。

    函数getifaddrs(int getifaddrs (struct ifaddrs **__ifap))获取本地网络接口信息,将之存储于链表中,链表头结点指针存储于__ifap中带回,函数执行成功返回0,失败返回-1,且为errno赋值。

  同时注意通过getifaddrs 返库ide指针需要手动释放,通过freeifaddrs(ifaddr);

代码示例如下:
   1: #include <arpa/inet.h>
   2: #include <ifaddrs.h>
   3: #include <netinet/in.h>
   4:  
   5: std::string FLAGS_ip_option = "IPV4"; // IPV4,IPV6,ALL
   6: std::string FLAGS_skip_if_name = "eth1,lo"; // eth name want to skip
   7: void GetLocalIPAddrs(vector<string>* ip_list) {
   8:   struct ifaddrs* if_addrs = NULL;
   9:   struct ifaddrs* ifa = NULL;
  10:   void* tmp_if_addr = NULL;
  11:   getifaddrs(&if_addrs);
  12:   for (ifa = if_addrs; ifa != NULL; ifa = ifa->ifa_next) {
  13:     if (FLAGS_skip_if_name.find(ifa->ifa_name) != string::npos) {  // skip eth
  14:       continue;
  15:     }
  16:     if (FLAGS_ip_option == "ALL" || FLAGS_ip_option == "IPV4") {
  17:       if (ifa->ifa_addr->sa_family == AF_INET) {  // check it is IPV4
  18:         tmp_if_addr = &((struct sockaddr_in*)ifa->ifa_addr)->sin_addr; // NOLINT
  19:         char addr_buffer[INET_ADDRSTRLEN];
  20:         inet_ntop(AF_INET, tmp_if_addr, addr_buffer, INET_ADDRSTRLEN);
  21:         string ip(addr_buffer);
  22:         ip_list->push_back(ip);
  23:       }
  24:     }
  25:     if (FLAGS_ip_option == "ALL" || FLAGS_ip_option == "IPV6") {
  26:       if (ifa->ifa_addr->sa_family == AF_INET6) {  // check it is IPV6
  27:         tmp_if_addr = &((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;  // NOLINT
  28:         char addr_buffer[INET6_ADDRSTRLEN];
  29:         inet_ntop(AF_INET6, tmp_if_addr, addr_buffer, INET6_ADDRSTRLEN);
  30:         string ip(addr_buffer);
  31:         ip_list->push_back(ip);
  32:       }
  33:     }
  34:   }
  35:   if (if_addrs != NULL) {
  36:     freeifaddrs(if_addrs);
  37:   }
  38: }                   
posted on 2013-01-24 16:37  @且听风吟@  阅读(400)  评论(0编辑  收藏  举报