基於visual c++之windows核心編程程式碼分析(59)實現網路簡單代理編程

來源:互聯網
上載者:User

  總得來說呢,就是一個網路訊號的跳轉,就是讓網路請求訊號通過第三方(代理)向你要訪問的那個網站發請求,然後這個網站會認為是第三方向他請求的,然後去驗證看是否合他的要求,當然訊號 接收也一樣,當你要接收訊號時,會認為接收到的是第三方的網路訊號,而不會去驗證,你實際上去訪問的這個網站的內容及地址!

通過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;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.