Write the Proxy server with VC ++ 6.0

xiaoxiao2021-03-06  53

One. principle

The structural principles of this program are as follows:

For each user's request (INTERNET request, the browser is issued), this program will start two threads, a request for local users

Data is sent to a remote Internet host, and another thread sends a response data of the remote host to the local requesting user.

two. Main function

UserToproxythread (Void * PParam): It is used to send local users to request data to remote hosts, from server line

Cheng role. When receiving the request from the local (LAN) user, it starts another own thread to listen to the request of other users, and read the connected

Request data received, then start the second thread proxyToServer () (this thread is used to connect the remote host), when the remote host is connected

After work, it sends the read local user request data to the remote host.

ProxyToServer (Void * PPARAM) can be used as a client service, which distributes the data sent by the remote host to the local

Ask for users.

three. Develop a running environment

This program is developed in the VC 6.0 environment, running in Win95 and WinNT4.0.

four. Detailed code

#include "stdafx.h"

#include "proxy.h"

#include // Winsocket API 2.0

#include

#include

#include

#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

CWINAPPPP;

Using namespace std;

Uint ProxyToServer (LPVOID PPARAM);

Uint UserToproxythread (Void * PPARAM);

Struct socketpair {

Socket User_Proxy; // Socket: Local Machine to Proxy Server

Socket Proxy_server; // Socket: Proxy Service to Remote Host

Bool isuser_proxyclosed; // Local machine to Proxy server status

Bool isproxy_serverclosed; // proxy service to remote host status

}

Struct proxyparam {

CHAR Address [256]; // Remote host address

Handle user_svrok; // proxy server to the connection status of the remote host

SocketPair * ppair; / ​​/ Maintain a set of socket pointers

Int port; // Used to join the port of the remote host

}; File: // This structure is used to exchange information with the remote host.

Socket Glisten_Socket; file: // Socket used to listen to.

Int StartServer () // Start service

{

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 = incoddr_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 service

{

CloseSocket (GLISTEN_SOCKET);

WSACLEANUP ();

Return 1;

}

File: // Analyze the received characters to get the remote host address

Int getaddressandport (Char * Str, Char * Address, INT * Port)

{

Char buf [buffsize], 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

IF (* (p i) == `/`) Break;

* (p i) = 0;

STRCPY (Address, P);

P = str, http);

For (int J = 0; j

* (p j) = ``; // remove the remote host name: get http://www.njust.edu.cn/

Http1.1 ==> Get / http1.1

* Port = 80; // Default HTTP port

}

Else

{// ftp, does not support, the following code can be omitted.

P = strstr (buf, ftp);

IF (! p) Return 0;

P = Strlen (FTP);

For (int i = 0; i

IF (* (p i) == `/`) Break; // Get The Remote Host

* (p i) = 0;

For (j = 0; j

IF (* (p j) == `:`) {* port = atoi (p j 1); // Get the port

* (p j) = 0;

}

Else * Port = 21;

STRCPY (Address, P);

P = str, ftp);

For (j = 0; j

* (p j) = ``;

}

Return 1;

}

/ / Take local data and send it to the remote host

Uint UserToproxythread (void * pparam)

{

Char buffer [buffs];

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, (strunt socketdr *) & from, & fromlen

AfxBeginThread (UserToproxythread, PParam); // Start another listener.

IF (msg_socket == invalid_socket)

{Printf ("/ NERROR in Accept"); Return-5;}

// read the first line of data from the customer

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", return, 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);

GetDressandport (Buffer, Proxyp.address, & Proxyp.Port);

PChildthread = AFXBEGINTHREAD (PROXYTOSERVER, (LPVOID) & proxyp); :: waitforsingleObject (proxyp.user_svrok, 60000); // Waiting for joint

:: 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", return, 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); // Should Check The

Return Value

Return 0;

}

/ / Read remote host data and send it to the local client

Uint proxytoserver (lpvoid pparam) {

ProxyParam * PPAR = (ProxyParam *) PPARAM;

Char buffer [buffs];

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 {/ * converat 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 (ppar-> user_svrok;

Return 0;

}

//

// Copy the resolved information inform the 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 ());

PPAR-> PPAIR-> isproxy_serverclosed = TRUE;

:: setEvent (ppar-> user_svrok;

Return -1;

}

#ifdef _Debug

Printf ("Client Connecting TO:% S / N", HP-> h_name;

#ENDIF

IF (Conn_Socket, Struct SockAddr *) & Server, SIZEOF (Server))

== SOCKET_ERROR) {

FPRINTF (stderr, "connect () failed:% d / n", wsagetlasterror ());

PPAR-> PPAIR-> isproxy_serverclosed = TRUE;

:: setEvent (ppar-> user_svrok;

Return -1;

}

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 / N", WsageTlasterror ());

CloseSocket (CONN_SOCKET);

PPAR-> PPAIR-> isproxy_serverclosed = TRUE;

Break;

}

Len = RetVal;

IF (retval == 0) {

Printf ("Server Closed Connection / N);

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 / n", wsagetlasterror ());

CloseSocket (PPAR-> PPAIR-> User_Proxy);

PPAR-> PPAIR-> iSuser_ProxyClosed = True;

Break;

}

#ifdef _Debug

Buffer [len] = 0;

Printf ("Received% D Bytes, Data [% s] from Server / N", RetVal, BUFFER;

#ENDIF

}

IF (PPAR-> PPAIR-> isproxy_serverclosed == false)

{

CloseSocket (PPAR-> PPAIR-> Proxy_server);

PPAR-> PPAIR-> isproxy_serverclosed = TRUE;

}

IF (ppar-> ppair-> iSuser_proxyclosed == false)

{CloseSocket (PPAR-> PPAIR-> User_Proxy);

PPAR-> PPAIR-> iSuser_ProxyClosed = True;

}

Return 1;

}

INT_Tmain (int Argc, tchar * argv [], tchar * envp [])

{

INT nretcode = 0;

// Initialize Socket

IF (! Afxwininit (:: getModuleHandle (Null), NULL, :: getcommandline (), 0))

{

// Error handling

CERR <<_t ("Fatal Error: MFC Initialization Failed") <

NRETCODE = 1;

}

Else

{

// The main program begins.

StartServer ();

While (1)

IF (getchar () == `q`) Break;

CloseServer ();

}

Return nretcode;

}

转载请注明原文地址:https://www.9cbs.com/read-116899.html

New Post(0)