通过C/C++语言配置IPNut 代理:
进入 IPNut 平台购买并获取信息,这里以静态IP为例(假如端口是 http://proxy.ipnut.com:28001,账号: ipnut,密码: 123456789)。
1. SOCKS5代理示例:socks5_proxy_demo.cpp #
/**
* SOCKS5代理演示 - C++
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class Socks5ProxyDemo {
private:
std::string proxy_host = "proxy.ipnut.com";
int proxy_port = 28001;
std::string proxy_username = "ipnut";
std::string proxy_password = "123456789";
public:
/**
* 连接到SOCKS5代理服务器
*/
int connectToSocks5Proxy() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
std::cerr << "创建socket失败" << std::endl;
return -1;
}
// 解析代理服务器地址
struct hostent* he = gethostbyname(proxy_host.c_str());
if (he == nullptr) {
std::cerr << "解析代理服务器地址失败" << std::endl;
close(sockfd);
return -1;
}
struct sockaddr_in proxy_addr;
memset(&proxy_addr, 0, sizeof(proxy_addr));
proxy_addr.sin_family = AF_INET;
proxy_addr.sin_port = htons(proxy_port);
memcpy(&proxy_addr.sin_addr, he->h_addr_list[0], he->h_length);
// 连接到代理服务器
if (connect(sockfd, (struct sockaddr*)&proxy_addr, sizeof(proxy_addr)) < 0) {
std::cerr << "连接到代理服务器失败" << std::endl;
close(sockfd);
return -1;
}
std::cout << "成功连接到SOCKS5代理服务器" << std::endl;
return sockfd;
}
/**
* SOCKS5认证握手
*/
bool socks5Authenticate(int sockfd) {
// SOCKS5握手包
std::vector handshake = {
0x05, // SOCKS版本5
0x02, // 认证方法数量
0x00, // 无认证
0x02 // 用户名密码认证
};
if (send(sockfd, handshake.data(), handshake.size(), 0) < 0) {
std::cerr << "发送握手包失败" << std::endl;
return false;
}
// 接收服务器响应
unsigned char response[2];
if (recv(sockfd, response, 2, 0) < 2) {
std::cerr << "接收握手响应失败" << std::endl;
return false;
}
if (response[0] != 0x05) {
std::cerr << "不支持的SOCKS版本" << std::endl;
return false;
}
// 如果需要用户名密码认证
if (response[1] == 0x02) {
return socks5UsernamePasswordAuth(sockfd);
} else if (response[1] != 0x00) {
std::cerr << "不支持的认证方法: " << (int)response[1] << std::endl;
return false;
}
return true;
}
/**
* SOCKS5用户名密码认证
*/
bool socks5UsernamePasswordAuth(int sockfd) {
std::vector auth_packet;
auth_packet.push_back(0x01); // 认证版本
auth_packet.push_back(proxy_username.length());
auth_packet.insert(auth_packet.end(), proxy_username.begin(), proxy_username.end());
auth_packet.push_back(proxy_password.length());
auth_packet.insert(auth_packet.end(), proxy_password.begin(), proxy_password.end());
if (send(sockfd, auth_packet.data(), auth_packet.size(), 0) < 0) {
std::cerr << "发送认证包失败" << std::endl;
return false;
}
unsigned char auth_response[2];
if (recv(sockfd, auth_response, 2, 0) < 2) {
std::cerr << "接收认证响应失败" << std::endl;
return false;
}
if (auth_response[0] != 0x01 || auth_response[1] != 0x00) {
std::cerr << "SOCKS5认证失败" << std::endl;
return false;
}
std::cout << "SOCKS5认证成功" << std::endl;
return true;
}
/**
* 通过SOCKS5代理连接目标服务器
*/
bool socks5ConnectToTarget(int sockfd, const std::string& target_host, int target_port) {
std::vector connect_packet;
connect_packet.push_back(0x05); // SOCKS版本
connect_packet.push_back(0x01); // CONNECT命令
connect_packet.push_back(0x00); // 保留
// 域名类型
connect_packet.push_back(0x03); // 域名
connect_packet.push_back(target_host.length());
connect_packet.insert(connect_packet.end(), target_host.begin(), target_host.end());
// 端口
connect_packet.push_back((target_port >> 8) & 0xFF);
connect_packet.push_back(target_port & 0xFF);
if (send(sockfd, connect_packet.data(), connect_packet.size(), 0) < 0) {
std::cerr << "发送连接请求失败" << std::endl;
return false;
}
// 接收连接响应
unsigned char connect_response[10];
int bytes_received = recv(sockfd, connect_response, 10, 0);
if (bytes_received < 2) {
std::cerr << "接收连接响应失败" << std::endl;
return false;
}
if (connect_response[0] != 0x05 || connect_response[1] != 0x00) {
std::cerr << "SOCKS5连接失败,代码: " << (int)connect_response[1] << std::endl;
return false;
}
std::cout << "通过SOCKS5代理成功连接到目标服务器" << std::endl;
return true;
}
/**
* 通过SOCKS5代理发送HTTP请求
*/
void sendHttpRequestViaSocks5(const std::string& target_host, int target_port, const std::string& path = "/ip") {
std::cout << "=== 通过SOCKS5代理发送HTTP请求 ===" << std::endl;
int sockfd = connectToSocks5Proxy();
if (sockfd < 0) return;
if (!socks5Authenticate(sockfd)) {
close(sockfd);
return;
}
if (!socks5ConnectToTarget(sockfd, target_host, target_port)) {
close(sockfd);
return;
}
// 发送HTTP请求
std::string http_request =
"GET " + path + " HTTP/1.1\r\n"
"Host: " + target_host + "\r\n"
"User-Agent: C++-SOCKS5-Proxy/1.0\r\n"
"Connection: close\r\n"
"\r\n";
if (send(sockfd, http_request.c_str(), http_request.length(), 0) < 0) {
std::cerr << "发送HTTP请求失败" << std::endl;
close(sockfd);
return;
}
// 接收HTTP响应
std::cout << "HTTP响应:" << std::endl;
char buffer[4096];
int bytes_received;
while ((bytes_received = recv(sockfd, buffer, sizeof(buffer) - 1, 0)) > 0) {
buffer[bytes_received] = '\0';
std::cout << buffer;
}
close(sockfd);
std::cout << std::endl;
}
/**
* 运行SOCKS5演示
*/
void runDemo() {
std::cout << "开始SOCKS5代理测试..." << std::endl;
// 测试连接到httpbin.org
sendHttpRequestViaSocks5("httpbin.org", 80, "/ip");
std::cout << std::endl;
sendHttpRequestViaSocks5("httpbin.org", 80, "/user-agent");
std::cout << std::endl;
sendHttpRequestViaSocks5("httpbin.org", 80, "/headers");
std::cout << "SOCKS5代理测试完成!" << std::endl;
}
};
int main() {
Socks5ProxyDemo demo;
demo.runDemo();
return 0;
}
2. HTTP代理示例:http_proxy_demo.cpp #
/**
* HTTP代理演示 - C++
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class HttpProxyDemo {
private:
std::string proxy_host = "proxy.ipnut.com";
int proxy_port = 28001;
std::string proxy_username = "ipnut";
std::string proxy_password = "123456789";
/**
* Base64编码
*/
std::string base64_encode(const std::string &input) {
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
std::string encoded;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
for (size_t idx = 0; idx < input.size(); idx++) {
char_array_3[i++] = input[idx];
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; i < 4; i++)
encoded += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i) {
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; j < i + 1; j++)
encoded += base64_chars[char_array_4[j]];
while(i++ < 3)
encoded += '=';
}
return encoded;
}
public:
/**
* 连接到HTTP代理服务器
*/
int connectToHttpProxy() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
std::cerr << "创建socket失败" << std::endl;
return -1;
}
// 解析代理服务器地址
struct hostent* he = gethostbyname(proxy_host.c_str());
if (he == nullptr) {
std::cerr << "解析代理服务器地址失败" << std::endl;
close(sockfd);
return -1;
}
struct sockaddr_in proxy_addr;
memset(&proxy_addr, 0, sizeof(proxy_addr));
proxy_addr.sin_family = AF_INET;
proxy_addr.sin_port = htons(proxy_port);
memcpy(&proxy_addr.sin_addr, he->h_addr_list[0], he->h_length);
// 连接到代理服务器
if (connect(sockfd, (struct sockaddr*)&proxy_addr, sizeof(proxy_addr)) < 0) {
std::cerr << "连接到代理服务器失败" << std::endl;
close(sockfd);
return -1;
}
std::cout << "成功连接到HTTP代理服务器" << std::endl;
return sockfd;
}
/**
* 通过HTTP代理发送CONNECT请求
*/
bool httpProxyConnect(int sockfd, const std::string& target_host, int target_port) {
// 构建代理认证头
std::string auth = proxy_username + ":" + proxy_password;
std::string encoded_auth = base64_encode(auth);
// 发送CONNECT请求
std::string connect_request =
"CONNECT " + target_host + ":" + std::to_string(target_port) + " HTTP/1.1\r\n"
"Host: " + target_host + ":" + std::to_string(target_port) + "\r\n"
"Proxy-Authorization: Basic " + encoded_auth + "\r\n"
"User-Agent: C++-HTTP-Proxy/1.0\r\n"
"Connection: keep-alive\r\n"
"\r\n";
if (send(sockfd, connect_request.c_str(), connect_request.length(), 0) < 0) {
std::cerr << "发送CONNECT请求失败" << std::endl;
return false;
}
// 读取代理响应
char buffer[4096];
int bytes_received = recv(sockfd, buffer, sizeof(buffer) - 1, 0);
if (bytes_received <= 0) {
std::cerr << "接收代理响应失败" << std::endl;
return false;
}
buffer[bytes_received] = '\0';
std::string response(buffer);
// 检查响应状态
if (response.find("HTTP/1.1 200") == std::string::npos &&
response.find("HTTP/1.0 200") == std::string::npos) {
std::cerr << "代理连接失败,响应: " << response << std::endl;
return false;
}
std::cout << "通过HTTP代理成功连接到目标服务器" << std::endl;
return true;
}
/**
* 通过HTTP代理发送HTTP请求
*/
void sendHttpRequestViaProxy(const std::string& target_host, int target_port, const std::string& path = "/ip") {
std::cout << "=== 通过HTTP代理发送HTTP请求 ===" << std::endl;
int sockfd = connectToHttpProxy();
if (sockfd < 0) return;
if (!httpProxyConnect(sockfd, target_host, target_port)) {
close(sockfd);
return;
}
// 发送HTTP请求
std::string http_request =
"GET " + path + " HTTP/1.1\r\n"
"Host: " + target_host + "\r\n"
"User-Agent: C++-HTTP-Proxy/1.0\r\n"
"Accept: application/json\r\n"
"Connection: close\r\n"
"\r\n";
if (send(sockfd, http_request.c_str(), http_request.length(), 0) < 0) {
std::cerr << "发送HTTP请求失败" << std::endl;
close(sockfd);
return;
}
// 接收HTTP响应
std::cout << "HTTP响应:" << std::endl;
char buffer[4096];
int bytes_received;
while ((bytes_received = recv(sockfd, buffer, sizeof(buffer) - 1, 0)) > 0) {
buffer[bytes_received] = '\0';
std::cout << buffer;
}
close(sockfd);
std::cout << std::endl;
}
/**
* 使用HTTP代理发送GET请求(直接方式)
*/
void sendGetRequestViaProxy(const std::string& target_url) {
std::cout << "=== 使用HTTP代理发送GET请求(直接方式) ===" << std::endl;
int sockfd = connectToHttpProxy();
if (sockfd < 0) return;
// 构建代理认证头
std::string auth = proxy_username + ":" + proxy_password;
std::string encoded_auth = base64_encode(auth);
// 发送完整的HTTP请求(代理会转发)
std::string http_request =
"GET " + target_url + " HTTP/1.1\r\n"
"Host: httpbin.org\r\n"
"User-Agent: C++-HTTP-Proxy-Direct/1.0\r\n"
"Proxy-Authorization: Basic " + encoded_auth + "\r\n"
"Accept: application/json\r\n"
"Connection: close\r\n"
"\r\n";
if (send(sockfd, http_request.c_str(), http_request.length(), 0) < 0) {
std::cerr << "发送HTTP请求失败" << std::endl;
close(sockfd);
return;
}
// 接收响应
std::cout << "HTTP响应:" << std::endl;
char buffer[4096];
int bytes_received;
while ((bytes_received = recv(sockfd, buffer, sizeof(buffer) - 1, 0)) > 0) {
buffer[bytes_received] = '\0';
std::cout << buffer;
}
close(sockfd);
std::cout << std::endl;
}
/**
* 运行HTTP代理演示
*/
void runDemo() {
std::cout << "开始HTTP代理测试..." << std::endl;
// 测试CONNECT方式
sendHttpRequestViaProxy("httpbin.org", 80, "/ip");
std::cout << std::endl;
sendHttpRequestViaProxy("httpbin.org", 80, "/user-agent");
// 测试直接方式
std::cout << std::endl;
sendGetRequestViaProxy("http://httpbin.org/headers");
std::cout << "HTTP代理测试完成!" << std::endl;
}
};
int main() {
HttpProxyDemo demo;
demo.runDemo();
return 0;
}
3. 代理测试工具:proxy_test_tool.cpp #
/**
* 代理测试工具 - C++
*/
#include
#include
#include "socks5_proxy_demo.cpp"
#include "http_proxy_demo.cpp"
class ProxyTestTool {
public:
/**
* 测试SOCKS5代理
*/
void testSocks5Proxy() {
std::cout << "测试 SOCKS5 代理:" << std::endl;
Socks5ProxyDemo socks5Demo;
// 简化测试 - 只测试连接和认证
int sockfd = socks5Demo.connectToSocks5Proxy();
if (sockfd >= 0) {
if (socks5Demo.socks5Authenticate(sockfd)) {
std::cout << "✅ SOCKS5 代理连接成功" << std::endl;
} else {
std::cout << "❌ SOCKS5 代理认证失败" << std::endl;
}
close(sockfd);
} else {
std::cout << "❌ SOCKS5 代理连接失败" << std::endl;
}
}
/**
* 测试HTTP代理
*/
void testHttpProxy() {
std::cout << "\n测试 HTTP 代理:" << std::endl;
HttpProxyDemo httpDemo;
int sockfd = httpDemo.connectToHttpProxy();
if (sockfd >= 0) {
std::cout << "✅ HTTP 代理连接成功" << std::endl;
close(sockfd);
} else {
std::cout << "❌ HTTP 代理连接失败" << std::endl;
}
}
/**
* 运行测试
*/
void runTests() {
std::cout << "=== 代理测试工具 ===" << std::endl;
testSocks5Proxy();
testHttpProxy();
std::cout << "\n代理测试完成!" << std::endl;
}
};
int main() {
ProxyTestTool tool;
tool.runTests();
return 0;
}
4. Makefile #
# Makefile for C++ Proxy Demo
CXX = g++
CXXFLAGS = -std=c++11 -Wall -Wextra -O2
TARGETS = socks5_demo http_demo proxy_test
all: $(TARGETS)
socks5_demo: socks5_proxy_demo.cpp
$(CXX) $(CXXFLAGS) -o socks5_demo socks5_proxy_demo.cpp
http_demo: http_proxy_demo.cpp
$(CXX) $(CXXFLAGS) -o http_demo http_proxy_demo.cpp
proxy_test: proxy_test_tool.cpp
$(CXX) $(CXXFLAGS) -o proxy_test proxy_test_tool.cpp
clean:
rm -f $(TARGETS)
.PHONY: all clean
5. 编译和运行说明:编译命令 #
# 编译所有目标
make all
# 或分别编译
make socks5_demo
make http_demo
make proxy_test
# 或手动编译
g++ -std=c++11 -Wall -Wextra -O2 -o socks5_demo socks5_proxy_demo.cpp
g++ -std=c++11 -Wall -Wextra -O2 -o http_demo http_proxy_demo.cpp
g++ -std=c++11 -Wall -Wextra -O2 -o proxy_test proxy_test_tool.cpp
6. 运行命令: #
# 运行SOCKS5代理演示
./socks5_demo
# 运行HTTP代理演示
./http_demo
# 运行代理测试工具
./proxy_test