官方给的链接打不开,而且里面的逻辑,每次都会打开文件,所以自己做了点个修改,发上来,借大家参考:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <string> #include <vector> #include <fstream> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> class IP17MON { public: static bool init(const std::string strPathToDataFile = "./17monipdb.dat") { if(is_init) { return true; } printf("Opening %s\n", strPathToDataFile.c_str()); std::ifstream ifDataFile(strPathToDataFile.c_str(), std::ios::binary); if (ifDataFile.is_open() == false) { printf("%m\n"); return false; } // std vector reserve vecDataFile.assign(std::istreambuf_iterator<char>(ifDataFile), std::istreambuf_iterator<char>()); printf("Load %lu bytes success\n", vecDataFile.size()); unsigned int uiIndexLen = 0; memcpy(&uiIndexLen, &vecDataFile[0], 4); uiIndexLen = ntohl(uiIndexLen); printf("uiIndexLen = %d\n", uiIndexLen); pIPIndex = &vecDataFile[4]; pIPData = &vecDataFile[uiIndexLen]; is_init = 1; return true; } static std::string find(const std::string strIP) { struct sockaddr_in stSockAddrInet; memset(&stSockAddrInet, 0, sizeof(struct sockaddr_in)); if(inet_aton(strIP.c_str(), &stSockAddrInet.sin_addr) == 0) { printf("convert error\n"); return ""; } unsigned int uiIP = ntohl(stSockAddrInet.sin_addr.s_addr); // atoi The string can contain additional characters after those // that form the integral number, which are ignored and have no // effect on the behavior of this function. int iFirst = atoi(strIP.c_str()); int iStart = 0; memcpy(&iStart, pIPIndex+(iFirst*4), 4); printf("iStart = %d\n", iStart); int iMaxComLen = pIPData - pIPIndex - 1024 - 4; int iIndexOffset = -1; unsigned char ucIndexLength = 0; for (iStart = iStart * 8 + 1024; iStart < iMaxComLen; iStart += 8) { unsigned int uiCurrIP = 0; memcpy(&uiCurrIP, pIPIndex+iStart, 4); uiCurrIP = ntohl(uiCurrIP); if (uiCurrIP >= uiIP) { iIndexOffset = 0; memcpy(&iIndexOffset, pIPIndex+iStart+4, 3); memcpy(&ucIndexLength, pIPIndex+iStart+7, 1); break; } } if (iIndexOffset == -1) { return ""; } std::string strRegion(pIPData + iIndexOffset - 1024, ucIndexLength); return strRegion; } public: static std::vector<char> vecDataFile; static char *pIPIndex, *pIPData; static int is_init; }; char *IP17MON::pIPIndex; char *IP17MON::pIPData; int IP17MON::is_init = 0; std::vector<char> IP17MON::vecDataFile; extern "C" const char *find_monip(const char *ip) { if (IP17MON::init() == false) { return ""; } return IP17MON::find(ip).c_str(); }