總得來說呢,就是一個網路訊號的跳轉,就是讓網路請求訊號通過第三方(代理)向你要訪問的那個網站發請求,然後這個網站會認為是第三方向他請求的,然後去驗證看是否合他的要求,當然訊號 接收也一樣,當你要接收訊號時,會認為接收到的是第三方的網路訊號,而不會去驗證,你實際上去訪問的這個網站的內容及地址!
通過Proxy 伺服器串連網路的優點
(1)設定使用者驗證和記賬功能,可按使用者進行記賬,沒有登記的使用者無權通過Proxy 伺服器訪問Internet網。並對使用者的訪問時間、訪問地點、資訊流量進行統計。
(2)對使用者進行分級管理,設定不同使用者的存取權限,對外界或內部的Internet地址進行過濾,設定不同的存取權限。
(3)增加緩衝器(Cache),提高訪問速度,對經常訪問的地址建立緩衝區,大大提高熱門網站的訪問效率。通常Proxy 伺服器都設定一個較大的硬碟緩衝區(可能高達幾個GB或更大),當有外界的資訊通過時,同時也將其儲存到緩衝區中,當其他使用者再訪問相同的資訊時,則直接由緩衝區中取出資訊,傳給使用者,以提高訪問速度。
(4)串連內網與Internet,充當防火牆(Firewall):因為所有內部網的使用者通過Proxy 伺服器訪問外界時,只映射為一個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 20480struct 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;}