Proxy.cpp
上传用户:sophiecyc
上传日期:2007-01-03
资源大小:7k
文件大小:10k
源码类别:

代理服务器

开发平台:

Visual C++

  1. // Proxy.cpp is very simple program to implement the HTTP proxy function.
  2. // To make it short and clear , some error tolerant codes are omitted.
  3. // Written by HU Zhongshan   
  4. // e-mail huzhongshan@hotmail.com OR yangjy@mail.njust.edu.cn
  5. // 1999-4-18
  6. #include "stdafx.h"
  7. #include "Proxy.h"
  8. #include <winsock2.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #ifdef _DEBUG
  13. #define new DEBUG_NEW
  14. #undef THIS_FILE
  15. static char THIS_FILE[] = __FILE__;
  16. #endif
  17. /////////////////////////////////////////////////////////////////////////////
  18. // The one and only application object
  19. #define HTTP  "http://"
  20. #define FTP   "ftp://"
  21. #define PROXYPORT    5060    //Proxy Listen Port
  22. #define BUFSIZE   10240      //Buffer size
  23. CWinApp theApp;
  24. using namespace std;
  25. UINT ProxyToServer(LPVOID pParam);
  26. UINT UserToProxyThread(void *pParam);
  27. struct SocketPair{
  28. SOCKET  user_proxy;      //socket : local machine to proxy server
  29. SOCKET  proxy_server;    //socket : proxy sever to remote server
  30. BOOL    IsUser_ProxyClosed; // status of local machine to proxy server
  31. BOOL    IsProxy_ServerClosed; // status of proxy server to remote server
  32. };
  33. struct ProxyParam{
  34. char Address[256];    // address of remote server
  35. HANDLE User_SvrOK;    // status of setup connection between proxy server and remote server
  36. SocketPair *pPair;    // pointer to socket pair
  37. int     Port;         // port which will be used to connect to remote server
  38. };                   //This struct is used to exchange information between threads.
  39. SOCKET    gListen_Socket;   
  40. int StartServer()
  41. {
  42.      WSADATA wsaData;
  43.  sockaddr_in local;
  44.  SOCKET listen_socket;
  45. if(::WSAStartup(0x202,&wsaData)!=0)
  46. {printf("nError in Startup session.n");WSACleanup();return -1;};
  47. local.sin_family=AF_INET;
  48. local.sin_addr.s_addr=INADDR_ANY;
  49. local.sin_port=htons(PROXYPORT);
  50. listen_socket=socket(AF_INET,SOCK_STREAM,0);
  51. if(listen_socket==INVALID_SOCKET)
  52. {printf("nError in New a Socket.");WSACleanup();return -2;}
  53. if(::bind(listen_socket,(sockaddr *)&local,sizeof(local))!=0)
  54. {printf("n Error in Binding socket."); WSACleanup();return -3; };
  55. if(::listen(listen_socket,5)!=0)
  56. {printf("n Error in Listen."); WSACleanup(); return -4;}
  57. gListen_Socket=listen_socket; 
  58. AfxBeginThread(UserToProxyThread,NULL);   //Start accept function
  59. return 1;
  60. }
  61. int CloseServer()
  62. {
  63. closesocket(gListen_Socket);
  64. WSACleanup();
  65. return 1;
  66. }
  67. //Analisys the string, to find the remote address
  68. int GetAddressAndPort( char * str, char *address, int * port)
  69. {
  70. char buf[BUFSIZE], command[512], proto[128], *p;
  71. int j;
  72. sscanf(str,"%s%s%s",command,buf,proto);
  73. p=strstr(buf,HTTP);
  74. //HTTP
  75. if(p)
  76. {
  77. p+=strlen(HTTP);
  78. for(int i=0;i<strlen(p);i++)
  79. if( *(p+i)=='/') break;
  80. *(p+i)=0;
  81. strcpy(address,p);
  82. p=strstr(str,HTTP);
  83. for(int j=0;j<i+strlen(HTTP);j++)
  84. *(p+j)=' ';  //to remove the host name: GET http://www.njust.edu.cn/ HTTP1.1  ==> GET / HTTP1.1
  85. *port=80;      //default http port 
  86. }
  87. else
  88. {//FTP, Not supported, and following code can be omitted.
  89.  p=strstr(buf,FTP);
  90.  if(!p) return 0;
  91.   p+=strlen(FTP);
  92. for(int i=0;i<strlen(p);i++)
  93. if( *(p+i)=='/') break;      //Get The Remote Host
  94. *(p+i)=0;
  95. for(j=0;j<strlen(p);j++)
  96. if(*(p+j)==':') 
  97. {*port=atoi(p+j+1);    //Get The Port
  98.      *(p+j)=0;
  99. }
  100.  else *port=21;                 
  101. strcpy(address,p);
  102. p=strstr(str,FTP);
  103. for(j=0;j<i+strlen(FTP);j++)
  104. *(p+j)=' ';
  105. }
  106. return 1; 
  107. }
  108. // Setup chanel and read data from local , send data to remote
  109. UINT UserToProxyThread(void *pParam)
  110. {
  111.  char Buffer[BUFSIZE];
  112.  int  Len;
  113.  sockaddr_in from;
  114.  SOCKET msg_socket;
  115.  int fromlen,retval;
  116.  SocketPair SPair;
  117.  ProxyParam ProxyP;
  118.  CWinThread *pChildThread;
  119.      fromlen=sizeof(from);
  120.  msg_socket=accept(gListen_Socket,(struct sockaddr*)&from,&fromlen);
  121.    AfxBeginThread(UserToProxyThread,pParam); //Start another thread to listen.
  122.  if( msg_socket==INVALID_SOCKET)
  123. { printf( "nError  in accept "); return -5;}
  124.  
  125. //recieve the first line of client
  126.  SPair.IsUser_ProxyClosed=FALSE;
  127.  SPair.IsProxy_ServerClosed=TRUE;
  128.  SPair.user_proxy=msg_socket;
  129.  retval=recv(SPair.user_proxy,Buffer,sizeof(Buffer),0);
  130.  
  131.  if(retval==SOCKET_ERROR)
  132. { printf("nError Recv"); 
  133.       if(SPair.IsUser_ProxyClosed==FALSE)
  134. {closesocket(SPair.user_proxy);
  135.  SPair.IsUser_ProxyClosed=TRUE;
  136. }
  137. }
  138.  if(retval==0)
  139. {printf("Client Close connectionn");
  140.      if(SPair.IsUser_ProxyClosed==FALSE)
  141. {closesocket(SPair.user_proxy);
  142.  SPair.IsUser_ProxyClosed=TRUE;
  143. }
  144. }
  145.  Len=retval;
  146. #ifdef _DEBUG
  147.  Buffer[Len]=0;
  148.  printf("n Received %d bytes,data[%s]from clientn",retval,Buffer);
  149. #endif
  150.  //
  151.  SPair.IsUser_ProxyClosed=FALSE;
  152.  SPair.IsProxy_ServerClosed=TRUE;
  153.  SPair.user_proxy=msg_socket;
  154.  ProxyP.pPair=&SPair;
  155.  ProxyP.User_SvrOK=CreateEvent(NULL,TRUE,FALSE,NULL);
  156.  
  157.  GetAddressAndPort( Buffer,ProxyP.Address,&ProxyP.Port);
  158.  pChildThread=AfxBeginThread(ProxyToServer,(LPVOID)&ProxyP);
  159.  ::WaitForSingleObject(ProxyP.User_SvrOK,60000);  //Wait for connection between proxy and remote server
  160.  ::CloseHandle(ProxyP.User_SvrOK);
  161.   while(SPair.IsProxy_ServerClosed ==FALSE && SPair.IsUser_ProxyClosed==FALSE)
  162.  {
  163.    retval=send(SPair.proxy_server,Buffer,Len,0);
  164.    if(retval==SOCKET_ERROR)
  165. { printf("n send() failed:error%dn",WSAGetLastError());
  166.      if(SPair.IsProxy_ServerClosed==FALSE)
  167. {
  168. closesocket(SPair.proxy_server);
  169. SPair.IsProxy_ServerClosed=TRUE;
  170. }
  171.   continue;
  172. }
  173.     retval=recv(SPair.user_proxy,Buffer,sizeof(Buffer),0);
  174.  
  175. if(retval==SOCKET_ERROR)
  176. { printf("nError Recv"); 
  177.       if(SPair.IsUser_ProxyClosed==FALSE)
  178. {closesocket(SPair.user_proxy);
  179.  SPair.IsUser_ProxyClosed=TRUE;
  180. }
  181.       continue;
  182. }
  183. if(retval==0)
  184. {printf("Client Close connectionn");
  185.      if(SPair.IsUser_ProxyClosed==FALSE)
  186. {closesocket(SPair.user_proxy);
  187.  SPair.IsUser_ProxyClosed=TRUE;
  188. }
  189.  break;
  190. }
  191. Len=retval;
  192. #ifdef _DEBUG
  193. Buffer[Len]=0;
  194.  printf("n Received %d bytes,data[%s]from clientn",retval,Buffer);
  195. #endif
  196.   } //End While
  197.      if(SPair.IsProxy_ServerClosed==FALSE)
  198. {
  199. closesocket(SPair.proxy_server);
  200. SPair.IsProxy_ServerClosed=TRUE;
  201. }
  202.  if(SPair.IsUser_ProxyClosed==FALSE)
  203. {closesocket(SPair.user_proxy);
  204.  SPair.IsUser_ProxyClosed=TRUE;
  205. }
  206. ::WaitForSingleObject(pChildThread->m_hThread,20000);  //Should check the reture value
  207. return 0;
  208. }
  209. // Read data from remote and send data to local
  210. UINT ProxyToServer(LPVOID pParam)
  211. {
  212.     ProxyParam * pPar=(ProxyParam*)pParam;
  213. char Buffer[BUFSIZE];
  214. char *server_name= "localhost";
  215. unsigned short port ;
  216. int retval,Len;
  217. unsigned int addr;
  218. int socket_type ;
  219. struct sockaddr_in server;
  220. struct hostent *hp;
  221. SOCKET  conn_socket;
  222. socket_type = SOCK_STREAM;
  223. server_name = pPar->Address;
  224. port = pPar->Port;
  225. if (isalpha(server_name[0])) {   /* server address is a name */
  226. hp = gethostbyname(server_name);
  227. }
  228. else  { /* Convert nnn.nnn address to a usable one */
  229. addr = inet_addr(server_name);
  230. hp = gethostbyaddr((char *)&addr,4,AF_INET);
  231. }
  232. if (hp == NULL ) {
  233. fprintf(stderr,"Client: Cannot resolve address [%s]: Error %dn",
  234. server_name,WSAGetLastError());
  235. ::SetEvent(pPar->User_SvrOK);
  236. return 0;
  237. }
  238. //
  239. // Copy the resolved information into the sockaddr_in structure
  240. //
  241. memset(&server,0,sizeof(server));
  242. memcpy(&(server.sin_addr),hp->h_addr,hp->h_length);
  243. server.sin_family = hp->h_addrtype;
  244. server.sin_port = htons(port);
  245. conn_socket = socket(AF_INET,socket_type,0); /* Open a socket */
  246. if (conn_socket <0 ) {
  247. fprintf(stderr,"Client: Error Opening socket: Error %dn",
  248. WSAGetLastError());
  249. pPar->pPair->IsProxy_ServerClosed=TRUE;
  250. ::SetEvent(pPar->User_SvrOK);
  251. return -1;
  252. }
  253. #ifdef _DEBUG
  254. printf("Client connecting to: %sn",hp->h_name);
  255. #endif
  256. if (connect(conn_socket,(struct sockaddr*)&server,sizeof(server))
  257. == SOCKET_ERROR) {
  258. fprintf(stderr,"connect() failed: %dn",WSAGetLastError());
  259. pPar->pPair->IsProxy_ServerClosed=TRUE;
  260. ::SetEvent(pPar->User_SvrOK);
  261. return -1;
  262. }
  263. pPar->pPair->proxy_server=conn_socket;
  264. pPar->pPair->IsProxy_ServerClosed=FALSE;
  265.     ::SetEvent(pPar->User_SvrOK);
  266. // cook up a string to send
  267. while(!pPar->pPair->IsProxy_ServerClosed &&!pPar->pPair->IsUser_ProxyClosed)
  268. {
  269. retval = recv(conn_socket,Buffer,sizeof (Buffer),0 );
  270. if (retval == SOCKET_ERROR ) {
  271. fprintf(stderr,"recv() failed: error %dn",WSAGetLastError());
  272. closesocket(conn_socket);
  273. pPar->pPair->IsProxy_ServerClosed=TRUE;
  274. break;
  275. }
  276. Len=retval;
  277. if (retval == 0) {
  278. printf("Server closed connectionn");
  279. closesocket(conn_socket);
  280. pPar->pPair->IsProxy_ServerClosed=TRUE;
  281. break;
  282. }
  283. retval = send(pPar->pPair->user_proxy,Buffer,Len,0);
  284. if (retval == SOCKET_ERROR) {
  285. fprintf(stderr,"send() failed: error %dn",WSAGetLastError());
  286. closesocket(pPar->pPair->user_proxy);
  287. pPar->pPair->IsUser_ProxyClosed=TRUE;
  288. break;
  289. }
  290. #ifdef _DEBUG
  291. Buffer[Len]=0;
  292. printf("Received %d bytes, data [%s] from servern",retval,Buffer);
  293. #endif
  294. }
  295. if(pPar->pPair->IsProxy_ServerClosed==FALSE)
  296. {
  297. closesocket(pPar->pPair->proxy_server);
  298. pPar->pPair->IsProxy_ServerClosed=TRUE;
  299. }
  300.  if(pPar->pPair->IsUser_ProxyClosed==FALSE)
  301. {closesocket(pPar->pPair->user_proxy);
  302.  pPar->pPair->IsUser_ProxyClosed=TRUE;
  303. }
  304.  return 1;
  305. }
  306. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  307. {
  308. int nRetCode = 0;
  309. // initialize MFC and print and error on failure
  310. if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
  311. {
  312. // TODO: change error code to suit your needs
  313. cerr << _T("Fatal Error: MFC initialization failed") << endl;
  314. nRetCode = 1;
  315. }
  316. else
  317. {
  318. // TODO: code your application's behavior here.
  319. StartServer();
  320. while(1)
  321. if(getchar()=='q') break;
  322. CloseServer();
  323. }
  324. return nRetCode;
  325. }