原理概述
nginx 运行在端口A,转发数据给端口B,C++ 监听端口B的数据。
本文例子
使用 C++ 和 nginx 获取客户端的IP地址
代码
nginx 配置
#user nobody;
worker_processes 1;events {worker_connections 1024;
}http {include mime.types;default_type application/octet-stream;sendfile on;keepalive_timeout 65;server {listen 2335;server_name localhost;# 转发 API 请求到 C++ 应用location / {proxy_pass http://localhost:5033/; # 假设 C++ 应用运行在 5033 端口proxy_http_version 1.1; # 使用 HTTP/1.1proxy_set_header Upgrade $http_upgrade; # 支持 WebSocketproxy_set_header Connection 'upgrade';proxy_set_header Host $host;proxy_cache_bypass $http_upgrade;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}}}
CPP代码
#include <iostream>
#include <WinSock2.h>
#include <string>#pragma comment(lib, "ws2_32.lib")using std::cout;
using std::endl;
using std::string;int main()
{WSADATA wsa;if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0){cout << "WSA Error" << endl;return 0;}sockaddr_in sd;sd.sin_family = AF_INET;sd.sin_port = htons(5033);sd.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");// socketSOCKET fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);if (fd == INVALID_SOCKET){cout << "socket error" << endl;return 0;}// bindif (bind(fd, (sockaddr *)(&sd), sizeof(sd)) == SOCKET_ERROR){cout << "bind error" << endl;return 0;}// listenlisten(fd, 10);sockaddr_in sd2;int sd2Size = sizeof(sd2);// acceptSOCKET clientFd = accept(fd, (sockaddr *)(&sd2), &sd2Size);if (clientFd == INVALID_SOCKET){cout << "客户端 socket error" << endl;return 0;}char buf[1024] = "";if (recv(clientFd, buf, 1024, 0) != 0){cout << "recv " << buf << endl;string str = buf;// 找到字符串"X-Forwarded-For:"的位置int pos1 = str.find("X-Forwarded-For:"); std::string sub = str.substr(pos1);int pos2 = sub.find("\n");string sub2 = sub.substr(0, pos2);std::cout << sub2 << std::endl;int pos3 = sub2.find(":");string sub3 = sub2.substr(pos3 + 2);std::cout << sub3 << std::endl;}closesocket(clientFd);closesocket(fd);WSACleanup();return 0;
}
操作步骤
先运行 nginx,然后运行CPP程序,最后在浏览器输入 localhost:2335即可
运行结果
只保留了关键信息,其他信息已抹去