总得来说呢,就是一个网络信号的跳转,就是让网络请求信号通过第三方(代理)向你要访问的那个网站发请求,然后这个网站会认为是第三方向他请求的,然后去验证看是否合他的要求,当然信号 接收也一样,当你要接收信号时,会认为接收到的是第三方的网络信号,而不会去验证,你实际上去访问的这个网站的内容及地址!
通过代理服务器连接网络的优点
(1)设置用户验证和记账功能,可按用户进行记账,没有登记的用户无权通过代理服务器访问Internet网。并对用户的访问时间、访问地点、信息流量进行统计。
(2)对用户进行分级管理,设置不同用户的访问权限,对外界或内部的Internet地址进行过滤,设置不同的访问权限。
(3)增加缓冲器(Cache),提高访问速度,对经常访问的地址创建缓冲区,大大提高热门站点的访问效率。通常代理服务器都设置一个较大的硬盘缓冲区(可能高达几个GB或更大),当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息,传给用户,以提高访问速度。
(4)连接内网与Internet,充当防火墙(Firewall):因为所有内部网的用户通过代理服务器访问外界时,只映射为一个IP地址,所以外界不能直接访问到内部网;同时可以设置IP地址过滤,限制内部网对外部的访问权限。
下面我们来亲自实践一个简单的网络代理
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <winsock2.h>
#include <io.h>
#pragma comment(lib, "ws2_32.lib")
#define MAXSIZE 20480
struct TransferSocket
{
SOCKET fd1;
SOCKET fd2;
};
void ClientThread(LPVOID data);
int ConnectHost(int SocketSer, char* server, int port);
//************************************************************************************
VOID main(int argc, char* argv[])
{
char ServerHost[256] = {0};
int ClientPort=0, ServerPort=0;
WSADATA wsadata;
WSAStartup(MAKEWORD(1, 1), &wsadata);
if (argc != 4)
{
printf("example: Proxy.exe 8181 68.13.145.77 8181");
return;
}
ClientPort = atoi(argv[1]);
strcpy(ServerHost, argv[2]);
ServerPort = atoi(argv[3]);
SOCKET SocketListen,SocketClient,SocketServer;
struct sockaddr_in remote;
int size;
char buffer[1024];
HANDLE hThread=NULL;
TransferSocket sock;
DWORD dwThreadID;
if (ClientPort > 65535 || ClientPort < 1)
{
printf("Client connectPort invalid.\r\n");
return;
}
if (ServerPort > 65535 || ServerPort < 1)
{
printf("Server connectPort invalid.\r\n");
return;
}
memset(buffer,0,1024);
//----------
SocketListen=socket(AF_INET,SOCK_STREAM,0);
if(SocketListen<=0)
{
printf("Create socket error.\r\n");
return;
}
//-----------
struct sockaddr_in srvaddr;
int on=1;
memset(&srvaddr, 0, sizeof(struct sockaddr));
srvaddr.sin_port=htons(ClientPort);
srvaddr.sin_family=AF_INET;
srvaddr.sin_addr.s_addr=htonl(INADDR_ANY);
setsockopt(SocketListen,SOL_SOCKET,SO_REUSEADDR, (char*)&on,sizeof(on));
if(bind(SocketListen,(struct sockaddr *)&srvaddr,sizeof(struct sockaddr))<0)
{
printf("Listen socket bind error.\r\n");
return;
}
if(listen(SocketListen,8)<0)
{
printf("Socket Listen error.\r\n");
return;
}
size=sizeof(struct sockaddr);
while(1)
{
printf("Waiting for Client ......\r\n");
if((SocketClient=accept(SocketListen,(struct sockaddr *)&remote,&size))<0)
{
printf("Accept error.\r\n");
continue;
}
printf("Accept a Client from %s:%d ......\r\n",
inet_ntoa(remote.sin_addr), ntohs(remote.sin_port));
SocketServer=socket(AF_INET,SOCK_STREAM,0);
if(SocketServer <= 0)
{
printf("Create socket error.\r\n");
closesocket(SocketClient);
return;
}
printf("Make a Connection to %s:%d ......\r\n",ServerHost,ServerPort);
if(ConnectHost(SocketServer,ServerHost,ServerPort)==0)
{
closesocket(SocketServer);
closesocket(SocketClient);
continue;
}
printf("Connect successed!\r\n");
sock.fd1 = SocketClient;
sock.fd2 = SocketServer;
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ClientThread, (LPVOID)&sock, 0, &dwThreadID);
if(hThread == NULL)
{
TerminateThread(hThread, 0);
return;
}
Sleep(1000);
printf("CreateThread successed!\r\n\n");
}
WSACleanup();
return;
}
void ClientThread(LPVOID data)
{
SOCKET fd1, fd2;
TransferSocket *sock;
struct timeval timeset;
fd_set readfd,writefd;
int result,i=0;
char read_in1[MAXSIZE],send_out1[MAXSIZE];
char read_in2[MAXSIZE],send_out2[MAXSIZE];
int read1=0,totalread1=0,send1=0;
int read2=0,totalread2=0,send2=0;
int sendcount1,sendcount2;
int maxfd;
int structsize1,structsize2;
char tmpbuf[100];
sock = (TransferSocket *)data;
fd1 = sock->fd1;
fd2 = sock->fd2;
memset(tmpbuf,0,100);
structsize1=sizeof(struct sockaddr);
structsize2=sizeof(struct sockaddr);
maxfd=max(fd1,fd2)+1;
memset(read_in1,0,MAXSIZE);
memset(read_in2,0,MAXSIZE);
memset(send_out1,0,MAXSIZE);
memset(send_out2,0,MAXSIZE);
timeset.tv_sec=1000;
timeset.tv_usec=0;
while(1)
{
FD_ZERO(&readfd);
FD_ZERO(&writefd);
FD_SET((UINT)fd1, &readfd);
FD_SET((UINT)fd1, &writefd);
FD_SET((UINT)fd2, &writefd);
FD_SET((UINT)fd2, &readfd);
result=select(maxfd,&readfd,&writefd,NULL,×et);
if((result<0) && (errno!=EINTR))
{
printf("Select error.\r\n");
break;
}
else if(result==0)
{
printf("Socket time out.\r\n");
break;
}
if(FD_ISSET(fd1, &readfd))
{
if(totalread1<MAXSIZE)
{
read1=recv(fd1, read_in1, MAXSIZE-totalread1, 0);
if((read1==SOCKET_ERROR) || (read1==0))
{
printf("Read client data error\r\n");
break;
}
memcpy(send_out1+totalread1,read_in1,read1);
totalread1+=read1;
memset(read_in1,0,MAXSIZE);
}
}
if(FD_ISSET(fd2, &writefd))
{
int err=0;
sendcount1=0;
while(totalread1>0)
{
send1=send(fd2, send_out1+sendcount1, totalread1, 0);
if(send1==0)break;
if((send1<0) && (errno!=EINTR))
{
printf("Send to server error.\r\n");
err=1;
break;
}
if((send1<0) && (errno==ENOSPC)) break;
sendcount1+=send1;
totalread1-=send1;
}
if(err==1) break;
if((totalread1>0) && (sendcount1>0))
{
memcpy(send_out1,send_out1+sendcount1,totalread1);
memset(send_out1+totalread1,0,MAXSIZE-totalread1);
}
else
memset(send_out1,0,MAXSIZE);
}
if(FD_ISSET(fd2, &readfd))
{
if(totalread2<MAXSIZE)
{
read2=recv(fd2,read_in2,MAXSIZE-totalread2, 0);
if(read2==0)break;
if((read2<0) && (errno!=EINTR))
{
printf("Read server data error\r\n\r\n");
break;
}
memcpy(send_out2+totalread2,read_in2,read2);
totalread2+=read2;
memset(read_in2,0,MAXSIZE);
}
}
if(FD_ISSET(fd1, &writefd))
{
int err2=0;
sendcount2=0;
while(totalread2>0)
{
send2=send(fd1, send_out2+sendcount2, totalread2, 0);
if(send2==0)break;
if((send2<0) && (errno!=EINTR))
{
printf("Send to client error.\r\n");
err2=1;
break;
}
if((send2<0) && (errno==ENOSPC)) break;
sendcount2+=send2;
totalread2-=send2;
}
if(err2==1) break;
if((totalread2>0) && (sendcount2 > 0))
{
memcpy(send_out2, send_out2+sendcount2, totalread2);
memset(send_out2+totalread2, 0, MAXSIZE-totalread2);
}
else
memset(send_out2,0,MAXSIZE);
}
Sleep(5);
}
closesocket(fd1);
closesocket(fd2);
printf("\r\n Closed The Two Socket.\r\n");
}
int ConnectHost(int SocketSer,char* server,int port)
{
struct sockaddr_in cliaddr;
struct hostent *ServerHost;
if(!(ServerHost=gethostbyname(server)))
{
printf("Gethostbyname(%s) error:%s\n",server,strerror(errno));
return(0);
}
memset(&cliaddr, 0, sizeof(struct sockaddr));
cliaddr.sin_family=AF_INET;
cliaddr.sin_port=htons(port);
cliaddr.sin_addr=*((struct in_addr *)ServerHost->h_addr);
if(connect(SocketSer,(struct sockaddr *)&cliaddr,sizeof(struct sockaddr))<0)
{
printf("Connect error.\r\n");
return(0);
}
return 1;
}