?? proxy32.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 + -