工作中一个方案可行性预研写的小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://blog.csdn.net/thinkingl/article/details/38328597