# 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 Port # Define bufsize 10240 // buffer size Cwinapp theapp; Using namespace STD; Uint proxytoserver (lpvoid pparam ); Uint usertoproxythread (void * pparam ); Struct socketpair { Socket user_proxy; // socket: Local Machine to proxy service machine Socket proxy_server; // socket: proxy server to remote host Bool isuser_proxyclosed; // The status from the local machine to the proxy service machine Bool isproxy_serverclosed; // proxy server to remote host status }; Struct proxyparam { Char Address [256]; // remote host address Handle user_svrok; // connection status from the proxy server to the remote host Socketpair * ppair; // maintain a set of socket pointers Int port; // port used to connect the remote host }; // This structure is used to exchange information between the proxy server and the remote host. Socket glisten_socket; // The socket used for listening. Int startserver () // start the service { 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); // start listening Return 1; } Int closeserver () // close the service { Closesocket (glisten_socket ); Wsacleanup (); Return 1; } // Analyze the received characters to obtain the remote host address Int getaddressandport (char * STR, char * address, int * port) { Char Buf [bufsize], command [512], proto [128], * P; Int J; Sscanf (STR, "% 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) = ''; // remove remote host name: Get http://www.njust.edu.cn/http1.1 ==> get/http1.1 * Port = 80; // default http port } Else {// FTP, not supported. The following Code It can be omitted. 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; } // Obtain local data and send it to the remote host Uint usertoproxythread (void * pparam) { Char buffer [bufsize]; Int Len; Sockaddr_in from; Socket msg_socket; Int fromlen, retval; Socketpair spair; Proxyparam proxyp; Cwinthread * pchildthread; Fromlen = sizeof (from ); Msg_socket = accept (glisten_socket, (struct sockaddr *) & from, & fromlen ); Afxbeginthread (usertoproxythread, pparam); // start another listener. If (msg_socket = invalid_socket) {Printf ("\ nerror in accept"); Return-5 ;} // Read the customer's first line of data 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 ("\ nerror Recv "); If (spair. isuser_proxyclosed = false) {Closesocket (spair. user_proxy ); Spair. isuser_proxyclosed = true; } } If (retval = 0) {Printf ("client close connection \ n "); If (spair. isuser_proxyclosed = false) {Closesocket (spair. user_proxy ); Spair. isuser_proxyclosed = true; } } Len = retval; # Ifdef _ debug Buffer [Len] = 0; Printf ("\ n received % d bytes, data [% s] From Client \ n", retval, buffer ); # Endif // Spair. isuser_proxyclosed = false; Spair. isproxy_serverclosed = true; Spair. user_proxy = msg_socket; Proxyp. ppair = & spair; Proxyp. user_svrok = createevent (null, true, false, null ); Getaddressandport (buffer, proxyp. Address, & proxyp. Port ); Pchildthread = afxbeginthread (proxytoserver, (lpvoid) & proxyp ); : Waitforsingleobject (proxyp. user_svrok, 60000); // wait for join : Closehandle (proxyp. user_svrok ); While (spair. isproxy_serverclosed = false & spair. isuser_proxyclosed = false) { Retval = Send (spair. proxy_server, buffer, Len, 0 ); If (retval = socket_error) {Printf ("\ n send () failed: Error % d \ n", wsagetlasterror ()); If (spair. isproxy_serverclosed = false) { Closesocket (spair. proxy_server ); Spair. isproxy_serverclosed = true; } Continue; } Retval = Recv (spair. user_proxy, buffer, sizeof (buffer), 0 ); If (retval = socket_error) {Printf ("\ nerror Recv "); If (spair. isuser_proxyclosed = false) {Closesocket (spair. user_proxy ); Spair. isuser_proxyclosed = true; } Continue; } If (retval = 0) {Printf ("client close connection \ n "); If (spair. isuser_proxyclosed = false) {Closesocket (spair. user_proxy ); Spair. isuser_proxyclosed = true; } Break; } Len = retval; # Ifdef _ debug Buffer [Len] = 0; Printf ("\ n received % d bytes, data [% s] From Client \ n", retval, buffer ); # Endif } // End while If (spair. isproxy_serverclosed = false) { Closesocket (spair. proxy_server ); Spair. isproxy_serverclosed = true; } If (spair. isuser_proxyclosed = false) {Closesocket (spair. user_proxy ); Spair. isuser_proxyclosed = true; } : Waitforsingleobject (pchildthread-> m_hthread, 20000); // shocould check the return value Return 0; } // Read the remote host data and send it to the local client Uint proxytoserver (lpvoid pparam ){ Proxyparam * PHA = (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 = PHA-> address; Port = PHA-> 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 \ n ", SERVER_NAME, wsagetlasterror ()); : Setevent (PHA-> 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);/* open a socket */ If (conn_socket <0 ){ Fprintf (stderr, "client: Error opening socket: Error % d \ n ", Wsagetlasterror ()); Ppair> isproxy_serverclosed = true; : Setevent (PHA-> user_svrok ); Return-1; } # Ifdef _ debug Printf ("Client Connecting to: % s \ n", HP-> h_name ); # Endif If (connect (conn_socket, (struct sockaddr *) & server, sizeof (server )) = Socket_error ){ Fprintf (stderr, "Connect () failed: % d \ n", wsagetlasterror ()); Ppair> isproxy_serverclosed = true; : Setevent (PHA-> user_svrok ); Return-1; } Ppair-> proxy_server = conn_socket; Ppair> isproxy_serverclosed = false; : Setevent (PHA-> user_svrok ); // Cook up a string to send While (! Ppair> isproxy_serverclosed &&! Ppair> isuser_proxyclosed) { Retval = Recv (conn_socket, buffer, sizeof (buffer), 0 ); If (retval = socket_error ){ Fprintf (stderr, "Recv () failed: Error % d \ n", wsagetlasterror ()); Closesocket (conn_socket ); Ppair> isproxy_serverclosed = true; Break; } Len = retval; If (retval = 0 ){ Printf ("server closed connection \ n "); Closesocket (conn_socket ); Ppair> isproxy_serverclosed = true; Break; } Retval = Send (Fig-> ppair-> user_proxy, buffer, Len, 0 ); If (retval = socket_error ){ Fprintf (stderr, "Send () failed: Error % d \ n", wsagetlasterror ()); Closesocket (Fig-> ppair-> user_proxy ); Ppair-> isuser_proxyclosed = true; Break; } # Ifdef _ debug Buffer [Len] = 0; Printf ("received % d bytes, data [% s] from server \ n", retval, buffer ); # Endif } If (PHA-> ppair-> isproxy_serverclosed = false) { Closesocket (PHA-> ppair-> proxy_server ); Ppair> isproxy_serverclosed = true; } If (PHA-> ppair-> isuser_proxyclosed = false) {Closesocket (Fig-> ppair-> user_proxy ); Ppair-> isuser_proxyclosed = true; } Return 1; } Int _ tmain (INT argc, tchar * argv [], tchar * envp []) { Int nretcode = 0; // Initialize the socket If (! Afxwininit (: getmodulehandle (null), null,: getcommandline (), 0 )) { // Handle errors Cerr <_ T ("Fatal error: MFC initialization failed") <Endl; Nretcode = 1; } Else { // The main program starts. Startserver (); While (1) If (getchar () = 'q') break; Closeserver (); } Return nretcode; } # Ifdef _ debug Printf ("Client Connecting to: % s \ n", HP-> h_name ); # Endif If (connect (conn_socket, (struct sockaddr *) & server, sizeof (server )) = Socket_error ){ Fprintf (stderr, "Connect () failed: % d \ n", wsagetlasterror ()); Ppair> isproxy_serverclosed = true; : Setevent (PHA-> user_svrok ); Return-1; } Ppair-> proxy_server = conn_socket; Ppair> isproxy_serverclosed = false; : Setevent (PHA-> user_svrok ); // Cook up a string to send While (! Ppair> isproxy_serverclosed &&! Ppair> isuser_proxyclosed) { Retval = Recv (conn_socket, buffer, sizeof (buffer), 0 ); If (retval = socket_error ){ Fprintf (stderr, "Recv () failed: Error % d \ n", wsagetlasterror ()); Closesocket (conn_socket ); Ppair> isproxy_serverclosed = true; Break; } Len = retval; If (retval = 0 ){ Printf ("server closed connection \ n "); Closesocket (conn_socket ); Ppair> isproxy_serverclosed = true; Break; } Retval = Send (Fig-> ppair-> user_proxy, buffer, Len, 0 ); If (retval = socket_error ){ Fprintf (stderr, "Send () failed: Error % d \ n", wsagetlasterror ()); Closesocket (Fig-> ppair-> user_proxy ); Ppair-> isuser_proxyclosed = true; Break; } # Ifdef _ debug Buffer [Len] = 0; Printf ("received % d bytes, data [% s] from server \ n", retval, buffer ); # Endif } If (PHA-> ppair-> isproxy_serverclosed = false) { Closesocket (PHA-> ppair-> proxy_server ); Ppair> isproxy_serverclosed = true; } If (PHA-> ppair-> isuser_proxyclosed = false) {Closesocket (Fig-> ppair-> user_proxy ); Ppair-> isuser_proxyclosed = true; } Return 1; } Int _ tmain (INT argc, tchar * argv [], tchar * envp []) { Int nretcode = 0; // Initialize the socket If (! Afxwininit (: getmodulehandle (null), null,: getcommandline (), 0 )) { // Handle errors Cerr <_ T ("Fatal error: MFC initialization failed") <Endl; Nretcode = 1; } Else { // The main program starts. Startserver (); While (1) If (getchar () = 'q') break; Closeserver (); } Return nretcode; }
|