⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxy32.cpp

📁 http代理服务器
💻 CPP
字号:
// proxy32.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "proxy32.h"

//#include <afxwin.h>
#include < winsock2.h > //WINSOCKET API 2。0 



#define HTTP "http://" 

#define FTP "ftp://" 

#define PROXYPORT 8080 //Proxy 端口 

#define BUFSIZE 10240 //缓冲区大小 


#pragma comment(lib,"ws2_32.lib")


//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。 



#define MAX_LOADSTRING 100


//////////////////////////////////////////////////////////////// 

//CWinApp theApp; 


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() //关闭服务 
{ 

	::shutdown(gListen_Socket,SD_SEND);
	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去掉远程主机名: GET http://www.njust.edu.cn/ HTTP1.1 == > GET / HTTP1.1
		
		//如果不是默认的80端口
		//要做处理
		int ilocation=-1;
		for(int i=0;i<strlen(address);i++)
		{
			if(address[i]==':')
			{

				ilocation=i;
				break;
			}
		}
		if(ilocation>0)
		{
			address[ilocation]=0;
			char *pch=&address[ilocation+1];
			*port=atoi(pch);
		}
		else
			*port=80; //缺省的 http 端口
	
		//分析接收到的字符,得到远程主机地址 

	} 
	else 
	{//FTP, 不支持, 下面的代码可以省略.
		p=strstr(buf,FTP); 
		if(!p) 
			return 0;
		p+=strlen(FTP);
		for(int i=0;i< strlen(p);i++) 
			if( *(p+i)=='/') 
				break; //Get The Remote Host
		*(p+i)=0;
		for(j=0;j< strlen(p);j++)
			if(*(p+j)==':') 
			{
				*port=atoi(p+j+1); //Get The Port
				*(p+j)=0; 
			} 
			else 
				*port=21; 
		strcpy(address,p); 
		p=strstr(str,FTP);
		for(j=0;j< i+strlen(FTP);j++)
			*(p+j)=' '; 
	} 
	return 1; 
} 

// 取到本地的数据,发往远程主机
UINT UserToProxyThread(void *pParam)
{ 
	char Buffer[BUFSIZE];
	int Len;
	sockaddr_in from;
	SOCKET msg_socket; 
	int fromlen,retval;
	SocketPair SPair; 
	ProxyParam ProxyP;

	CWinThread *pChildThread;
	HANDLE hChildThread;
	fromlen=sizeof(from);
	msg_socket=accept(gListen_Socket,(struct sockaddr*)&from,&fromlen); 

	//hChildThread=::CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)UserToProxyThread,pParam,NULL,NULL);    /// add via netwalker
	AfxBeginThread(UserToProxyThread,pParam); //启动另一侦听. 

	if( msg_socket==INVALID_SOCKET) 
	{ 
		/////printf( " Error in accept ");
		return -5;
	} 
	//读客户的第一行数据
	SPair.IsUser_ProxyClosed=FALSE;
	SPair.IsProxy_ServerClosed=TRUE; 
	SPair.user_proxy=msg_socket;
	retval=recv(SPair.user_proxy,Buffer,sizeof(Buffer),0);
	if(retval==SOCKET_ERROR)
	{ 
		/////printf(" Error Recv");
		if(SPair.IsUser_ProxyClosed==FALSE)
		{
			::shutdown(SPair.user_proxy,SD_SEND);
			closesocket(SPair.user_proxy); 
			SPair.IsUser_ProxyClosed=TRUE;

		} 
	//	MessageBox(0,"error receive",0,0);
		return 0;

	} 
	if(retval==0) 
	{
		/////printf("Client Close connection ");
		if(SPair.IsUser_ProxyClosed==FALSE)
		{
			::shutdown(SPair.user_proxy,SD_SEND);
			closesocket(SPair.user_proxy);
			SPair.IsUser_ProxyClosed=TRUE; 
		}
	//	MessageBox(0,"close connection by client",0,0);
		return 0;
	} 
	Len=retval; 
#ifdef _DEBUG Buffer[Len]=0; 
	/////printf(" Received %d bytes,data[%s]from client ",retval,Buffer); 
#endif //
	SPair.IsUser_ProxyClosed=FALSE;
	SPair.IsProxy_ServerClosed=TRUE; 
	SPair.user_proxy=msg_socket;
	SocketPair *sp;
	sp=new SocketPair;
	sp->IsProxy_ServerClosed=SPair.IsProxy_ServerClosed;
	sp->IsUser_ProxyClosed=SPair.IsUser_ProxyClosed;
	sp->user_proxy=msg_socket;
	sp->proxy_server=0; //SPair.proxy_server;
	ProxyP.pPair=sp; 
	ProxyP.User_SvrOK=CreateEvent(NULL,TRUE,FALSE,NULL);
	//memcpy(p,(void *)&ProxyParam,sizeof(ProxyParam));
	GetAddressAndPort( Buffer,ProxyP.Address,&ProxyP.Port);


	ProxyParam *p;
	p=new ProxyParam;
//	p=new ProxyParam; 
	strcpy(p->Address,ProxyP.Address );

	p->Port=ProxyP.Port;
	p->pPair=ProxyP.pPair;
	p->User_SvrOK=ProxyP.User_SvrOK;

	pChildThread=AfxBeginThread(ProxyToServer,p);
	CString str;
	str.Format("address=%s port=%d and start ProxyToServer thread ok\n",ProxyP.Address,ProxyP.Port);
	::OutputDebugString(str); 
//	HANDLE hthread=::CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)ProxyToServer,&ProxyP,NULL,NULL);

//	::WaitForSingleObject(hthread,60000); //等待联结 	
	::WaitForSingleObject(ProxyP.User_SvrOK,60000); //等待联结 

	SPair.IsProxy_ServerClosed=p->pPair->IsProxy_ServerClosed;
	SPair.IsUser_ProxyClosed=p->pPair->IsUser_ProxyClosed;
	SPair.proxy_server=p->pPair->proxy_server;
	SPair.user_proxy=p->pPair->user_proxy;
	::OutputDebugString("after wait for thread ProxyToServer for 60m ok and we continue\n");

//	::CloseHandle(hthread); 
	::CloseHandle(ProxyP.User_SvrOK);
	while(sp->IsProxy_ServerClosed ==FALSE && sp->IsUser_ProxyClosed==FALSE) 
	//		while(SPair.IsProxy_ServerClosed ==FALSE && SPair.IsUser_ProxyClosed==FALSE) 
	{
		retval=send(SPair.proxy_server,Buffer,Len,0); 
		if(retval==SOCKET_ERROR) 
		{ 
			/////printf(" send() failed:error%d ",WSAGetLastError()); 
			if(SPair.IsProxy_ServerClosed==FALSE) 
			{ 
				::shutdown(SPair.proxy_server,SD_SEND);
				closesocket(SPair.proxy_server);
				SPair.IsProxy_ServerClosed=TRUE;
			} 
			continue; 
		}

		::OutputDebugString("send data and wait to recvive data from \n ");

		retval=recv(SPair.user_proxy,Buffer,sizeof(Buffer),0); 
		if(retval==SOCKET_ERROR)
		{
			/////printf(" Error Recv");
			if(SPair.IsUser_ProxyClosed==FALSE)
			{
				::shutdown(SPair.user_proxy,SD_SEND);
				closesocket(SPair.user_proxy);
				SPair.IsUser_ProxyClosed=TRUE;
			}
			continue; 
		} 

		::OutputDebugString("recv data in UserToProxyThread \n");

		if(retval==0) 
		{
			/////printf("Client Close connection ");
			if(SPair.IsUser_ProxyClosed==FALSE)
			{
				::shutdown(SPair.user_proxy,SD_SEND);
				closesocket(SPair.user_proxy); 
				SPair.IsUser_ProxyClosed=TRUE;
			} 
			break; 
		} 
		Len=retval;
#ifdef _DEBUG Buffer[Len]=0;
		/////printf(" Received %d bytes,data[%s]from client ",retval,Buffer); 
#endif } //End While 
		if(SPair.IsProxy_ServerClosed==FALSE) 
		{ 
			::shutdown(SPair.proxy_server,SD_SEND);
			closesocket(SPair.proxy_server); 
			SPair.IsProxy_ServerClosed=TRUE;
		} 
		if(SPair.IsUser_ProxyClosed==FALSE)
		{
			::shutdown(SPair.user_proxy,SD_SEND);
			closesocket(SPair.user_proxy);
			SPair.IsUser_ProxyClosed=TRUE; 
		} 
	//	::WaitForSingleObject(hChildThread,20000); //Should check the return value
		
		::OutputDebugString("we quit now\n");
		::WaitForSingleObject(pChildThread->m_hThread,20000); //Should check the return value
		delete sp;
		delete p;
		return 0; 
}
}
// 读取远程主机数据,并发往本地客户机
UINT ProxyToServer(LPVOID pParam)
{
	ProxyParam *pPar =(ProxyParam*)pParam; 
	char Buffer[BUFSIZE]; 
	char *server_name= "localhost";
	unsigned short port ;
	int retval,Len;
	unsigned int addr;
	int socket_type ; 
	struct sockaddr_in server;
	struct hostent *hp;
	SOCKET conn_socket; 
	socket_type = SOCK_STREAM;
	server_name = pPar->Address; 
	port = pPar->Port;
	if (isalpha(server_name[0]))
	{ /* server address is a name */ 
		hp = gethostbyname(server_name); 
	} 
	else 
	{ /* Convert nnn.nnn address to a usable one */
		addr = inet_addr(server_name); 
		hp = gethostbyaddr((char *)&addr,4,AF_INET);
	} 
	if (hp == NULL )
	{ 
//		fprintf(stderr,"Client: Cannot resolve address [%s]: Error %d ", server_name,WSAGetLastError());
		::SetEvent(pPar->User_SvrOK);
		return 0; 
	} // 
	// Copy the resolved information into the sockaddr_in structure // 
	memset(&server,0,sizeof(server));
	memcpy(&(server.sin_addr),hp->h_addr,hp->h_length);
	server.sin_family = hp->h_addrtype; 
	server.sin_port = htons(port); 
	conn_socket = socket(AF_INET,socket_type,0); /* 打开一个 socket */ 
	if (conn_socket < 0 )
	{ 
	//	fprintf(stderr,"Client: Error Opening socket: Error %d ", WSAGetLastError());
		pPar->pPair->IsProxy_ServerClosed=TRUE; 
		::SetEvent(pPar->User_SvrOK);
		return -1;
	} 
#ifdef _DEBUG /////printf("Client connecting to: %s ",hp- >h_name);
#endif 
	if (connect(conn_socket,(struct sockaddr*)&server,sizeof(server)) == SOCKET_ERROR)
	{ 
//		fprintf(stderr,"connect() failed: %d ",WSAGetLastError()); 
		pPar->pPair->IsProxy_ServerClosed=TRUE; 
		::SetEvent(pPar->User_SvrOK); 
		::OutputDebugString("faint,we connect to server error\n");
		return -1;
	}
	::OutputDebugString("ok,we connect to server ok\n");

	pPar->pPair->proxy_server=conn_socket; 
	pPar->pPair->IsProxy_ServerClosed=FALSE;
	::SetEvent(pPar->User_SvrOK); // cook up a string to send 
	while(!pPar->pPair->IsProxy_ServerClosed &&!pPar->pPair->IsUser_ProxyClosed) 
	{
		retval = recv(conn_socket,Buffer,sizeof (Buffer),0 );
		if (retval == SOCKET_ERROR )
		{ 
//			fprintf(stderr,"recv() failed: error %d ",WSAGetLastError());
			::shutdown(conn_socket,SD_SEND);
			closesocket(conn_socket); 
			pPar->pPair->IsProxy_ServerClosed=TRUE;
			break; 
		}

		::OutputDebugString("recv ok in ProxyToServer\n");
		::OutputDebugString(Buffer);
		::OutputDebugString("\n,,,,,,,,,,,,\n");

		Len=retval;
		if (retval == 0) 
		{ 
			/////printf("Server closed connection ");
			closesocket(conn_socket); 
			pPar->pPair->IsProxy_ServerClosed=TRUE;
			break;
		} 
		retval = send(pPar->pPair->user_proxy,Buffer,Len,0); 
		if (retval == SOCKET_ERROR)
		{ 
//			fprintf(stderr,"send() failed: error %d ",WSAGetLastError());
			::shutdown(pPar->pPair->user_proxy,SD_SEND);
			closesocket(pPar->pPair->user_proxy);
			pPar->pPair->IsUser_ProxyClosed=TRUE;
			DWORD ret=::GetLastError();
			CString str;
			str.Format("error in ProxyToServer which errror code is %d\n",ret);

			::OutputDebugString("");
			break;
		} 
		::OutputDebugString("send data to user who use proxy ok in ProxyToServer\n");
#ifdef _DEBUG Buffer[Len]=0;
		/////printf("Received %d bytes, data [%s] from server ",retval,Buffer); 
#endif 
	}  /// end while
	if(pPar->pPair->IsProxy_ServerClosed==FALSE)
	{ 
		::shutdown(pPar->pPair->proxy_server,SD_SEND);
		closesocket(pPar->pPair->proxy_server); 
			pPar->pPair->IsProxy_ServerClosed=TRUE;
			::OutputDebugString("close socket of proxy_server\n");
	} 

	if(pPar->pPair->IsUser_ProxyClosed==FALSE)
	{
		::shutdown(pPar->pPair->user_proxy,SD_SEND);
		closesocket(pPar->pPair->user_proxy);
		pPar->pPair->IsUser_ProxyClosed=TRUE;
		::OutputDebugString("close user_proxy\n");
	}
	::OutputDebugString("a session finished\n\n");
	return 1; 
} 

int StartProxy()
{
	StartServer();
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -