相关推荐
C++ 获取当前设备公网IP
2024-11-10 18:32

void getDomainIP(const char * domain, char * ip) { char ** pptr = NULL; int i = 0; char szHostName[256] = {}; struct hostent * pHostEntry = gethostbyname(domain); if (pHostEntry != NULL) { char szIpBuff[32] = {0};  for (i = 1, pptr = pHostEntry->h_addr_list; *pptr != NULL; ++pptr )  {  memset(szIpBuff, 0, sizeof(szIpBuff));  const char* szIpRet = inet_ntop(pHostEntry->h_addrtype, *pptr, szIpBuff, sizeof(szIpBuff)); // inet_ntop的返回值为NULL,则表示失败,否则返回相应的IP地址(此时szIpRet指向的是szIpBuff) if (szIpBuff != NULL) { memcpy(ip, szIpRet, sizeof(char[16])); } } } }

C++ 获取当前设备公网IP

std::string getIpFromHttpResponse(std::string response) { if (!response.empty()) { // 去掉尾部空白行 response.erase(response.find_last_not_of(" ") + 1); // 获取最后一行 std::string::size_type pos = response.find_last_of(" "); bool isGetIp = pos > 0 && pos < response.length(); response = isGetIp ? response.substr(pos, response.length()) : ""; // 判断是否是合法的ip int tmp1, tmp2, tmp3, tmp4; int i = sscanf(response.c_str(), "%d.%d.%d.%d", &tmp1, &tmp2, &tmp3, &tmp4); // 若ip非法则返回空 if (i != 4 || tmp1 > 255 || tmp2 > 255 || tmp3 > 255 || tmp4 > 255) { response = ""; } else { char tmp[20]; snprintf(tmp, sizeof(tmp), "%d.%d.%d.%d", tmp1, tmp2, tmp3, tmp4); response = tmp; HW_WRITE_LOG(log_info, "%s", response.c_str()); } } return response; }

std::string httpRequestIp(const char * domain) { char ipAddress[16]; memset(ipAddress, 0, sizeof(char[16])); getDomainIP(domain, ipAddress); char tmpReq[200]; sprintf(tmpReq, "GET http://%s/ HTTP/1.1 HOST: %s ", domain, domain); std::string request = (std::string)tmpReq; int port = 80;

std::string response; int resp_leng; char buffer[1024]; int sock;

#ifdef WIN32 struct sockaddr_in serveraddr; WSADATA wsaData;

//init winsock if (WSAStartup(MAKEWORd(2, 0), &wsaData) != 0) HW_WRITE_LOG(log_error, "WSAStartup() failed");

//open socket if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) HW_WRITE_LOG(log_error, "socket() failed");

//connect memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = inet_addr(ipAddress); serveraddr.sin_port = htons((unsigned short) port); if (connect(sock, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0) HW_WRITE_LOG(log_error, "connect() failed");

//send request if (send(sock, request.c_str(), request.length(), 0) != request.length()) HW_WRITE_LOG(log_error, "send() sent a different number of bytes than expected");

#else int error; struct sockaddr_in addr;

if((sock = socket(AF_INET,SOCK_STREAM,0))<0) { HW_WRITE_LOG(log_error, "Error 01: creating socket failed!"); return ""; }

addr.sin_family = AF_INET; addr.sin_port = htons(port); inet_aton(ipAddress,&addr.sin_addr); //this should be the ip of the server I'm contacting

error = connect(sock,(sockaddr*)&addr,sizeof(addr)); if(error!=0) { HW_WRITE_LOG(log_error, "Error 02: conecting to server failed!"); return ""; }

send(sock,request.c_str(),request.length(),0);

#endif

//get response response = ""; resp_leng= 1024; int revlen = 0; while (resp_leng == 1024) { resp_leng = recv(sock, (char*)&buffer, 1024, 0); revlen += resp_leng; if (resp_leng>0) response+= std::string(buffer).substr(0,resp_leng); }

std::string answer (response);

#if _WIN32 WSACleanup(); #endif answer = getIpFromHttpResponse(answer); return answer; } std::string GetPublicIP() { //char * domain = "checkip.amazonaws.com"; //std::string answer = httpRequestIp(domain); // 从多个http域名获取机器使用的外网ip,若获取失败则使用后面的其他域名 std::string domains[3] = {"bot.whatismyipaddress.com", "api.ipify.org", "icanhazip.com"}; std::string answer = ""; int num = sizeof(domains) / sizeof(domains[0]); for (int i = 0; i <= num - 1; i++) { const char * domain = domains[i].c_str(); answer = httpRequestIp(domain); if (!answer.empty()) { break; } }

    以上就是本篇文章【C++ 获取当前设备公网IP】的全部内容了,欢迎阅览 ! 文章地址:http://zleialh.xhstdz.com/quote/64829.html 
     栏目首页      相关文章      动态      同类文章      热门文章      网站地图      返回首页 物流园资讯移动站 http://zleialh.xhstdz.com/mobile/ , 查看更多   
发表评论
0评