工作中一个方案可行性预研写的小Demo,一晚上搞定的小程序.
主要功能是一个Http透明转发:
1.监听一个端口, 接收浏览器的连接请求.
2. 接收浏览器发出的请求数据, 将这些转发给一个指定的服务器.
3. 接收服务器的应答,将应答发送给浏览器.
代码都在一个文件中:
// httptranschannel.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "httptranschannel.h" #include <iostream> #include <string> #ifdef _DEBUG #define new DEBUG_NEW #endif const int PORT_LOCAL = 8084; //const char* SERVER_IP = "192.168.84.133"; //const int SERVER_PORT = 80; const int PACKAGE_BUFFER_SIZE = 100*1024; // 分包大小. SOCKET g_listenSocket = INVALID_SOCKET; SOCKET g_acceptSocket = INVALID_SOCKET; SOCKET g_serverSocket = INVALID_SOCKET; // 同服务器之间的连接Socket. // 唯一的应用程序对象 CWinApp theApp; using namespace std; int InitSocket() { // Initialize Winsock WSADATA wsaData; int iResult = 0; iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != NO_ERROR) { wprintf(L"WSAStartup() failed with error: %d\n", iResult); return 1; } return 0; } int ListenSocket() { if ( g_listenSocket == INVALID_SOCKET ) { int iResult = 0; sockaddr_in service; //---------------------- // Create a SOCKET for listening for incoming connection requests. g_listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (g_listenSocket == INVALID_SOCKET) { wprintf(L"socket function failed with error: %ld\n", WSAGetLastError()); WSACleanup(); return 1; } //---------------------- // The sockaddr_in structure specifies the address family, // IP address, and port for the socket that is being bound. service.sin_family = AF_INET; service.sin_addr.s_addr = ADDR_ANY; // inet_addr("127.0.0.1"); service.sin_port = htons(PORT_LOCAL); iResult = bind(g_listenSocket, (SOCKADDR *) & service, sizeof (service)); if (iResult == SOCKET_ERROR) { wprintf(L"bind function failed with error %d\n", WSAGetLastError()); iResult = closesocket(g_listenSocket); if (iResult == SOCKET_ERROR) wprintf(L"closesocket function failed with error %d\n", WSAGetLastError()); WSACleanup(); return 1; } //---------------------- // Listen for incoming connection requests // on the created socket if (listen(g_listenSocket, SOMAXCONN) == SOCKET_ERROR) wprintf(L"listen function failed with error: %d\n", WSAGetLastError()); wprintf(L"Listening on socket...\n"); //---------------------- // Create a SOCKET for accepting incoming requests. wprintf(L"Waiting for client to connect...\n"); } //---------------------- // Accept the connection. g_acceptSocket = accept(g_listenSocket, NULL, NULL); if (g_acceptSocket == INVALID_SOCKET) { wprintf(L"accept failed with error: %ld\n", WSAGetLastError()); closesocket(g_listenSocket); WSACleanup(); return 1; } else wprintf(L"Client connected.\n"); //g_acceptSocket = accept(g_listenSocket, NULL, NULL); //if (g_acceptSocket == INVALID_SOCKET) { // wprintf(L"accept failed with error: %ld\n", WSAGetLastError()); // closesocket(g_listenSocket); // WSACleanup(); // return 1; //} else // wprintf(L"Client connected.\n"); return 0; } int DestroySocket() { if ( INVALID_SOCKET != g_listenSocket ) { int iResult = closesocket(g_listenSocket); if (iResult == SOCKET_ERROR) { wprintf(L"closesocket function failed with error %d\n", WSAGetLastError()); WSACleanup(); return 1; } } WSACleanup(); return 0; } int ReceivFromSocket( SOCKET hSocket, char* pBuf, const int bufLen, int& dataLen, bool& disconnected ) { disconnected = false; fd_set fdSocket; // 所有可用套节字集合 FD_ZERO(&fdSocket); FD_SET( hSocket, &fdSocket); timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; int nHasData = select( 1,&fdSocket, NULL, NULL, &tv) ; if ( SOCKET_ERROR == nHasData ) { cout << "ReceivFromSocket select fail! er: " << WSAGetLastError() << endl; disconnected = true; return -1; } else if( 1 == nHasData ) { dataLen = recv( hSocket, pBuf, bufLen, 0 ); // 返回0说明正常断开连接了. disconnected = (dataLen == 0); return 0; } else if( 0 == nHasData ) { return 0; } else { cout << "ReceivFromSocket select return :" << nHasData << endl; } return -1; } int Connect2Server( const char* serverIp, const int serverPort ) { if ( g_serverSocket == INVALID_SOCKET ) { sockaddr_in server; //---------------------- // Create a SOCKET for listening for incoming connection requests. g_serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (g_listenSocket == INVALID_SOCKET) { wprintf(L"socket function failed with error: %ld\n", WSAGetLastError()); WSACleanup(); return 1; } //---------------------- // The sockaddr_in structure specifies the address family, // IP address, and port for the socket that is being bound. server.sin_family = AF_INET; server.sin_addr.s_addr = inet_addr( serverIp ); server.sin_port = htons( serverPort ); int result = connect( g_serverSocket, (SOCKADDR *)&server, sizeof( server ) ); if ( 0 != result ) { // 连接失败. cout << "Connect to server fail! ip: " << serverIp << " port: " << serverPort << " er: " << result << endl; // 销毁. closesocket( g_serverSocket ); g_serverSocket = INVALID_SOCKET; return -1; } } return 0; } int Send2Socket( SOCKET hSock, const char* pBuf, const int dataLen ) { // 将数据发送给Server. int sendLen = 0; while( sendLen < dataLen ) { int sendRet = send( hSock, pBuf + sendLen, dataLen - sendLen, 0 ); if ( sendRet < 0 ) { cout << "Send Data 2 server fail! ret: " << sendRet << " ec: " << WSAGetLastError() << endl; return -1; } else { sendLen += sendRet; } } return 0; } int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; HMODULE hModule = ::GetModuleHandle(NULL); if (hModule != NULL) { // 初始化 MFC 并在失败时显示错误 if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0)) { // TODO: 更改错误代码以符合您的需要 _tprintf(_T("错误: MFC 初始化失败\n")); nRetCode = 1; } else { string serverIp; int serverPort = 0; while( serverIp.empty() ) { cout << "Please type in server ip: "; cin >> serverIp; } while( serverPort == 0 ) { cout << "Please type in server port: "; cin >> serverPort; } // 初始化 InitSocket(); while(1) { int sleepTime = 50; if ( g_acceptSocket == INVALID_SOCKET ) { // 监听端口,处理新连接. ListenSocket(); } else { // 连接服务端 Connect2Server( serverIp.c_str(), serverPort ); // 新连接中,接收数据. char clientDataBuf[ PACKAGE_BUFFER_SIZE ] = {0}; int dataLen = 0; bool disconnected = false; ReceivFromSocket( g_acceptSocket, clientDataBuf, sizeof( clientDataBuf ), dataLen, disconnected ); if( disconnected ) { cout << "accept socket disconnect!" << endl; closesocket( g_acceptSocket ); g_acceptSocket = INVALID_SOCKET; } // 建立同服务端的新连接,将数据转发. if ( dataLen > 0 ) { // 如果有数据, 就不等待. 否则等待. sleepTime = 0; if ( g_serverSocket != INVALID_SOCKET ) { Send2Socket( g_serverSocket, clientDataBuf, dataLen ); } } // 接收服务端的数据,将数据发送给浏览器. if ( g_serverSocket != INVALID_SOCKET ) { char serverDataBuf[ PACKAGE_BUFFER_SIZE ] = {0}; int serverDataLen = 0; bool serverDisconnected = false; ReceivFromSocket( g_serverSocket, serverDataBuf, sizeof( serverDataBuf ), serverDataLen, serverDisconnected ); if ( serverDataLen > 0 ) { // 如果有数据, 就不等待. 否则等待. sleepTime = 0; Send2Socket( g_acceptSocket, serverDataBuf, serverDataLen ); } if ( serverDisconnected ) { cout << "Server disconnect! " << endl; closesocket( g_serverSocket ); g_serverSocket = INVALID_SOCKET; // 也和浏览器断链. closesocket( g_acceptSocket ); g_acceptSocket = INVALID_SOCKET; } } } Sleep( sleepTime ); } } } else { // TODO: 更改错误代码以符合您的需要 _tprintf(_T("错误: GetModuleHandle 失败\n")); nRetCode = 1; } return nRetCode; }
HTTP转发小Demo
时间: 2025-01-03 23:03:58