背景
业务需要在访问某个接口的时候需要实时获取到当前机器的各网卡的ip信息,以下代码仅供参考。
代码实现
#include <iostream> #include <map> #include <net/if.h> #include <netinet/in.h> #include <arpa/inet.h> #include <ifaddrs.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <netdb.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/socket.h> void PaddingSpecNetInfoByName(const char *szDevName, std::map<std::string, std::string> &netMap) { int s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { fprintf(stderr, "Create socket failed!errno=%d", errno); return; } struct ifreq ifr; unsigned char mac[6]; unsigned long nIP, nNetmask, nBroadIP; std::string netName = std::string(szDevName); // printf("name : %s \n", szDevName); auto iter = netMap.find(netName); if (iter == netMap.end()) { strcpy(ifr.ifr_name, szDevName); if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { nIP = 0; } else { nIP = *(unsigned long *)&ifr.ifr_broadaddr.sa_data[2]; } printf("IP addr: %s \n", inet_ntoa(*(in_addr *)&nIP)); netMap.insert(make_pair(netName, std::string(inet_ntoa(*(in_addr *)&nIP)))); } close(s); } void GetCurrentNetCardInfo(std::map<std::string, std::string> &netMap) { FILE *f = fopen("/proc/net/dev", "r"); if (!f) { fprintf(stderr, "Open /proc/net/dev failed!errno:%dn", errno); return; } char szLine[512]; fgets(szLine, sizeof(szLine), f); fgets(szLine, sizeof(szLine), f); while (fgets(szLine, sizeof(szLine), f)) { char szName[128] = {0}; sscanf(szLine, "%s", szName); int nLen = strlen(szName); if (nLen <= 0) continue; if (szName[nLen - 1] == ':') szName[nLen - 1] = 0; std::string netName = std::string(szName); // printf("name : %s \n", szName); if ((netName.find("eth") != std::string::npos) || (netName.find("en") != std::string::npos)) { PaddingSpecNetInfoByName(szName, netMap); } } fclose(f); f = NULL; } int main() { std::map<std::string, std::string> curMap; GetCurrentNetCardInfo(curMap); return 0; }
运行结果如下:
注意:代码对网卡做了过滤,只能获取到以 eth 和 en 开头的网卡的ip地址。