常用的代理服务器软件有procy sever 2.0以及WinGate等等。利用VC 6.0强大功能也可以编
写出自己的代理服务器应用软件。本文介绍了具体的实现方法。 
一. 原理 
本程序的结构原理如下: 
对于每一个用户的请求(Internet 
请求,由浏览器发出),本程序将启动两个线程,一个把本地用户的请求数据发送到远程的
Internet主机,另一个线程把远程主机的回应数据发送到本地请求用户。 
二. 主要函数 
UserToProxyThread ( void * pParam ) 
:它是用来把本地用户请求数据发送到远程主机的,起服务器线程角色。当接到本地(局域
网)用户的请求,它就启动另一个自身线程,以侦听别的用户的请求,并读出已接收到的请
求数据,接着启动第二个线程ProxyToServer()(这个线程用来连接远程主机),当远程主
机连接成功后,它把已读出的本地用户请求数据发送到远程主机。 
ProxyToServer ( void * pParam) 
,可以被当作是客户端服务,它把远程主机发送来的数据分发给本地请求用户。 
三. 开发运行环境 
本程序是在VC++6.0环境下开发的,在Win95 和 WinNT4.0下运行正常。 
四. 详细代码 
#include "stdafx.h" 
#include "Proxy.h" 
#include < winsock2.h > //WINSOCKET API 2。0 
#include < stdlib.h > 
#include < stdio.h > 
#include < string.h > 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
//////////////////////////////////////////////////////////////// 
#define HTTP "http://"; 
#define FTP "ftp://"; 
#define PROXYPORT 5001 //Proxy 端口 
#define BUFSIZE 10240 //缓冲区大小 
CWinApp theApp; 
using namespace std; 
UINT ProxyToServer(LPVOID pParam); 
UINT UserToProxyThread(void *pParam); 
struct SocketPair{ 
SOCKET user_proxy; //socket : 本地机器到PROXY 服务机 
SOCKET proxy_server; //socket : PROXY 服务机到远程主机 
BOOL IsUser_ProxyClosed; // 本地机器到PROXY 服务机状态 
BOOL IsProxy_ServerClosed; // PROXY 服务机到远程主机状态 
}; 
struct ProxyParam{ 
char Address[256]; // 远程主机地址 
HANDLE User_SvrOK; // PROXY 服务机到远程主机的联结状态 
SocketPair *pPair; // 维护一组SOCKET的指针 
int Port; // 用来联结远程主机的端口 
}; //这个结构用来PROXY SERVER与远程主机的信息交换. 
SOCKET gListen_Socket; //用来侦听的SOCKET。 
int StartServer() //启动服务 
{ 
WSADATA wsaData; 
sockaddr_in local; 
SOCKET listen_socket; 
if(::WSAStartup(0x202,&wsaData)!=0) 
{printf("\nError in Startup session.\n");WSACleanup();return 
-1;}; 
local.sin_family=AF_INET; 
local.sin_addr.s_addr=INADDR_ANY; 
local.sin_port=htons(PROXYPORT); 
listen_socket=socket(AF_INET,SOCK_STREAM,0); 
if(listen_socket==INVALID_SOCKET) 
{printf("\nError in New a Socket.");WSACleanup();return -2;} 
if(::bind(listen_socket,(sockaddr *)&local,sizeof(local))!=0) 
{printf("\n Error in Binding socket."); WSACleanup();return -3; 
}; 
if(::listen(listen_socket,5)!=0) 
{printf("\n Error in Listen."); WSACleanup(); return -4;} 
gListen_Socket=listen_socket; 
AfxBeginThread(UserToProxyThread,NULL); //启动侦听 
return 1; 
} 
int CloseServer() //关闭服务 
{ 
closesocket(gListen_Socket); 
WSACleanup(); 
return 1; 
} 
//分析接收到的字符,得到远程主机地址 
int GetAddressAndPort( char * str, char *address, int * port) 
{ 
char buf[BUFSIZE], command[512], proto[128], *p; 
int j; 
sscanf(str,"%s%s%s",command,buf,proto); 
p=strstr(buf,HTTP); 
//HTTP 
if(p) 
{ 
p+=strlen(HTTP); 
for(int i=0;i< strlen(p);i++) 
if( *(p+i)==`/`) break; 
*(p+i)=0; 
strcpy(address,p); 
p=strstr(str,HTTP); 
for(int j=0;j< i+strlen(HTTP);j++) 
*(p+j)=` `; //去掉远程主机%C。 
		 |