VS2017下如何用C++获取电脑公网IP?附实现代码
Hey there! You're working on integrating a public IP grabber into your IP handler (to store addresses in a database) using Visual Studio 2017, purely for learning purposes. Let's get your code properly formatted and break down how it works:
Solution Code
IpHandler.h
#pragma once #include <string> using std::string; class IpHandler { static string website_HTML; static void get_Website(string url); static char buffer[10000]; public: IpHandler(); static string GetExternalIp(); ~IpHandler(); };
IpHandler.cpp
#include "stdafx.h" #include "IpHandler.h" #define _WINSOCK_DEPRECATED_NO_WARNINGS #define _WINSOCK_DEPRECATED #include <string.h> #include <winsock2.h> #include <windows.h> #include <iostream> #include <vector> #include <locale> #include <sstream> #pragma comment(lib,"ws2_32.lib") using std::cout; using std::locale; using std::istringstream; string IpHandler::website_HTML = ""; char IpHandler::buffer[10000]; IpHandler::IpHandler() { } void IpHandler::get_Website(string url) { WSADATA wsaData; SOCKET Socket; SOCKADDR_IN SockAddr; struct hostent *host; string get_http = "GET / HTTP/1.1\r\nHost: " + url + "\r\nConnection: close\r\n\r\n"; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { cout << "WSAStartup failed.\n"; system("pause"); return; } Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); host = gethostbyname(url.c_str()); SockAddr.sin_port = htons(80); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = *((unsigned long*)host->h_addr); if (connect(Socket, (SOCKADDR*)(&SockAddr), sizeof(SockAddr)) != 0) { cout << "Could not connect"; system("pause"); return; } send(Socket, get_http.c_str(), strlen(get_http.c_str()), 0); int nDataLength; while ((nDataLength = recv(Socket, buffer, 10000, 0)) > 0) { int i = 0; while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') { website_HTML += buffer[i]; i += 1; } } closesocket(Socket); WSACleanup(); } string IpHandler::GetExternalIp() { locale local; char lineBuffer[200][80] = { ' ' }; char ip_address[16]; int lineIndex = 0; get_Website("api.ipify.org"); for (int i = 0; i < website_HTML.length(); ++i) { website_HTML[i] = tolower(website_HTML[i], local); } istringstream ss(website_HTML); string stoken; while (getline(ss, stoken, '\n')) { strcpy_s(lineBuffer[lineIndex], stoken.c_str()); int dot = 0; for (int ii = 0; ii < strlen(lineBuffer[lineIndex]); ii++) { if (lineBuffer[lineIndex][ii] == '.') dot++; if (dot >= 3) { dot = 0; strcpy_s(ip_address, lineBuffer[lineIndex]); } } lineIndex++; } return ip_address; } IpHandler::~IpHandler() { }
Quick Implementation Notes
- This uses
api.ipify.org, a free service that returns only your public IPv4 address as plain text—making parsing straightforward. - The
get_Websitemethod handles establishing a TCP connection via Winsock2, sending an HTTP GET request, and reading the response into a static buffer. GetExternalIp()fetches the response, then scans for a string with at least 3 dots (a key marker of an IPv4 address) to extract the public IP. Since ipify returns only the IP, you could simplify this parsing to just returnwebsite_HTMLdirectly after fetching if you want to cut down on unnecessary code.
内容的提问来源于stack exchange,提问作者CraftedGaming
相关产品推荐
相关产品推荐

