• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            focus on linux, c/c++, lua

            sock代理服務(wù)原理(TCP穿透)[轉(zhuǎn)載]

            sock代理分為sock4代理和 sock5代理。sock4支持TCP(事實僅支持TCP),無需用戶名、密碼驗證;sock5支持TCP和UDP,根據(jù)代理服務(wù)器設(shè)置是否需要用戶名、密碼認證。TCP和UDP代理工作原理產(chǎn)不多,UDP代理網(wǎng)上多的是,google一下即可。這里只講TCP代理工作原理。
            sock代理工作原理大致如下:
            1。[需要代理方]向服務(wù)器發(fā)出請求信息;
            2。[代理方]應(yīng)答;
            3。[需要代理方]接到應(yīng)答后發(fā)送向[代理方]發(fā)送目的ip和端口;
            4。[代理方]與目的連接;
            5。[代理方]將[需要代理方]發(fā)出的信息傳到目的方,將目的方發(fā)出的信息傳到[需要代理方];
            6。代理完成。
            下面對sock4和sock5的代理工作原理流程分別詳細說明,并給出示例代碼。
            sock4的TCP代理工作流程:
            1。我們首先還是連接服務(wù)器,然后發(fā)送數(shù)據(jù)給服務(wù)器。由于是無用戶密碼驗證,我們需要發(fā)送9個字節(jié)的數(shù)據(jù),展開寫為 04 01 + 目標(biāo)端口(2字節(jié)) + 目標(biāo)IP(4字節(jié)) + 00,其中目標(biāo)端口和目標(biāo)IP就是我們真正要連接的服務(wù)器端口和服務(wù)器地址;
            2。代理服務(wù)器返回8字節(jié)的數(shù)據(jù),我們只要判斷第二字節(jié)是否為90即可,若是90連接成功,否則失敗.剩下的操作和不存在代理服務(wù)器一樣,可直接用發(fā)送\接受數(shù)據(jù)。
            sock5的TCP代理工作流程:
            1。向服務(wù)器的代理端口建立tcp連接。一般為1080;
            2。向服務(wù)器發(fā)送  05 02 00 02(此為16進制碼,以下同),讓代理服務(wù)器選擇認證方式 ;
                 05
                 02 這里確認2種認證方式 無需認證和需要認證,只需要驗證一種方式,可以直接發(fā)送05 01 00查詢服務(wù)器是否支持無認證代理方式;
                 00 不需要認證;
                 02 需要認證;
            3。如果接到 05 00 則是可以代理或則05 02需要認證,這里只需要判斷第二字節(jié)就行;
                 如果需要認證,需要向服務(wù)器發(fā)送01 用戶名長度(2字節(jié))用戶名 密碼長度(2字節(jié))密碼,然后接收服務(wù)器返回數(shù)據(jù),如果第二字節(jié)為   00,則認證通過,否則無法認證,則連接失敗;
            4。發(fā)送 05 01 00 01 + 目的地址(4字節(jié))+ 目的端口(2字節(jié)),目的地址和端口都是16進制碼(不是字符串)。
                 例202.103.190.27 - 7201
                 則發(fā)送的信息為:05 01 00 01 CA 67 BE 1B 1C 21
                 (CA=202 67=103 BE=190 1B=27 1C21=7201)
            5。接收代理服務(wù)器返回的數(shù)據(jù),我們只要判斷第二字節(jié)是否為00即表示代理連接完成;
            6。以后操作和直接與目的方進行TCP連接相同。

            //代理服務(wù)器登錄
            CString g_proxyserver = "";
            int  g_proxyport = 1080;
            CString g_proxyuser 
            = "";
            CString g_proxypwd 
            = "";
            int  g_proxyid = 3;  //2 - sock4代理 3 - sock5代理
            char server_name[100]= {0};  //真正的服務(wù)器地址
            int  server_port=8000;   //真正的服務(wù)器端口
            SOCKET ConnecToProxyServer()
            {
             SOCKADDR_IN ToAddr;
             SOCKET m_hSocketpop 
            = socket(AF_INET, SOCK_STREAM ,0);  // SOCK_DGRAM;
             memset(&ToAddr, 0sizeof(ToAddr));
             ToAddr.sin_family 
            = AF_INET;
             ToAddr.sin_addr.s_addr 
            = inet_addr(g_proxyserver);//這是我的SOCKS服務(wù)器
             ToAddr.sin_port = htons(g_proxyport); 
             
            int retErr = connect(m_hSocketpop,(SOCKADDR*)&ToAddr,sizeof(ToAddr));
             
            if(retErr == SOCKET_ERROR)
             
            {
              closesocket(m_hSocketpop);
              
            return -1;
             }

             
            char buf[100= {0};
             
            if(g_proxyid == 3//sock5 代理方式
             {
              
            // 讓PROXY選擇認證方法
              buf[0= 0x05;
              buf[
            1= 0x02//確認2種認證方式 無需認證和需要認證
              buf[2= 0x00// 無需認證
              buf[3= 0x02// 需要認證
              if(send(m_hSocketpop,(const far char*)buf,4,0== SOCKET_ERROR)
              
            {
               closesocket(m_hSocketpop);
               
            return -1;
              }

              Sleep(
            100);
              
            if(recv(m_hSocketpop,buf,10,0== SOCKET_ERROR)
              
            {
               closesocket(m_hSocketpop);
               
            return -1;
              }

              
            if(buf[1== 0x02)
              
            {//需要認證
               char userStr[128= {0};
               userStr[
            0]=0x01;
               userStr[
            1]=g_proxyuser.GetLength();
               strcpy(userStr
            +2,g_proxyuser);
               userStr[
            2+g_proxyuser.GetLength()]=g_proxypwd.GetLength();
               strcpy(userStr
            +3+g_proxyuser.GetLength(),g_proxypwd);
               
            int result=send(m_hSocketpop,userStr,strlen(userStr), 0);
               
            if(result == SOCKET_ERROR)
               
            {
                closesocket(m_hSocketpop);
                
            return -1;
               }

               Sleep(
            100);
               
            char validateChar[2= {1};
               result
            =recv(m_hSocketpop,validateChar,20);
               
            if(result == SOCKET_ERROR)
               
            {
                closesocket(m_hSocketpop);
                
            return -1;
               }

               
            if(validateChar[1]!='\x00')
               
            {//認證失敗
                closesocket(m_hSocketpop);
                
            return -1;
               }

              }

              
            // 向PROXY服務(wù)器發(fā)送CONNECT 請求,
              memset(buf, 0100);
              buf[
            0= 0x05;
              buf[
            1= 0x01// connection request.
              buf[2= 0x00// reserved!
              buf[3= 0x01// address type:Ip V4 ;
              *((ULONG*)(buf+4))=inet_addr(server_name);
              
            *((USHORT*)(buf+8))=htons(server_port);
              
            if(send(m_hSocketpop,(const far char*)buf,10,0== SOCKET_ERROR)
              
            {
               closesocket(m_hSocketpop);
               
            return -1;
              }

              Sleep(
            100);
              
            // 接收PROXY服務(wù)器返回的REPLY
              memset(buf, 1100);
              
            if(recv(m_hSocketpop,buf, 20,0== SOCKET_ERROR)
              
            {
               closesocket(m_hSocketpop);
               
            return -1;
              }

              
            if(buf[1!= 0// 只有當(dāng)?shù)诙€字節(jié)為0時,才表示成功。
              {
            //   printf("Cannot connect to the remote server!\n");
               closesocket(m_hSocketpop);
               
            return -1;
              }

            //  theApp.m_ClientSocket.Attach(m_hSocketpop);
             }

             
            if(g_proxyid == 2//sock4 代理方式
             {
              
            int result;
              memset(buf, 
            0100);
              buf[
            0= 0x04;
              buf[
            1= 0x01// connection request.
              *((USHORT*)(buf+2))=htons(server_port);
              
            *((ULONG*)(buf+4))=inet_addr(server_name);
              buf[
            8= 0x00;
              result 
            = send(m_hSocketpop, (const far char*)buf, 90);
              
            if(result == SOCKET_ERROR)
              
            {
               closesocket(m_hSocketpop);
               
            return -1;
              }

              Sleep(
            100);
              
            char EchoStr[10];
              memset(EchoStr,
            0,10);
              result
            =recv(m_hSocketpop,EchoStr,80);
              
            if(result == SOCKET_ERROR)
              
            {
               closesocket(m_hSocketpop);
               
            return -1;
              }

              
            if(EchoStr[1!= 90)
              
            {
               closesocket(m_hSocketpop);
               
            return -1;
              }

            //  theApp.m_ClientSocket.Attach(m_hSocketpop);
             }

             
            return m_hSocketpop;
            }

            調(diào)用方式:
              strcpy(server_name, theApp.m_ServerIP);
              server_port 
            = 8080;
              SOCKET m_socket 
            = ConnecToProxyServer();
              
            if(m_socket == -1)
              
            {
                    
            return 0;
              }

              
            int type = 1000;
              send(m_socket, (
            char*)&type, sizeof(int), 0);


            SOCK5如何用代理UDP連接

            1。向服務(wù)器的1080端口建立tcp連接

            2。向服務(wù)器發(fā)送 05 01 00

            3。如果接到 05 00 則是可以代理

            4。發(fā)送 05 03 00 01 00 00 00 00 + 本地UDP端口(2字節(jié))

            5。服務(wù)器返回 05 00 00 01 +服務(wù)器地址+端口

            7.需要申請方發(fā)送
            00 00 00 01 +目的地址IP(4字節(jié))+目的端口 +所要發(fā)送的信息

            8。當(dāng)有數(shù)據(jù)報返回時
            向需要代理方發(fā)出00 00 00 01 +來源地址IP(4字節(jié))+來源端口 +接受的信息
             
            使用sock5代理時TCP數(shù)據(jù):
            客戶端   sock5服務(wù)器
            SYN
               ACKSYN
            ACK
            05 01 00 00 00 00
               05 00 00 00 00 00
            05 01 00 03 0E 31 39 32 2E 31 36 38 2E 37 35 2E 31 31 34 00 6E (.....192.168.75.114.n)
               05 00 00 01 C0 A8 4D 56 08 D4
            ACK
               +OK X1 NT-POP3 Server iflytek.com (IMail 8.15 228888-9)..
            USER hjma..
               +OK send your password..
            PASS xxxxxxx..
               +OK maildrop locked and ready..
            STAT..
               +OK 0 0..
            QUIT..
               +OK POP3 Server saying Good-Bye..
            ACKFIN
               ACK
               ACKFIN
            ACK  

            posted on 2010-06-08 13:36 zuhd 閱讀(7119) 評論(0)  編輯 收藏 引用 所屬分類: c/c++

            国产高潮国产高潮久久久| 色综合久久久久综合99| 久久久久亚洲av无码专区| 久久人人妻人人爽人人爽| 久久水蜜桃亚洲av无码精品麻豆 | 好久久免费视频高清| 国产综合久久久久久鬼色| 亚洲国产精品久久| 久久亚洲AV无码精品色午夜 | 无码超乳爆乳中文字幕久久| 99久久99这里只有免费费精品| 91超碰碰碰碰久久久久久综合| 久久国产欧美日韩精品免费| 俺来也俺去啦久久综合网| 久久国产香蕉一区精品| 久久久久免费看成人影片| 99久久国产主播综合精品| 伊人久久久AV老熟妇色| 国内精品久久久久久麻豆| 亚洲国产另类久久久精品| 久久国产三级无码一区二区| 国内精品久久久久久99蜜桃| 亚洲精品97久久中文字幕无码 | 伊人精品久久久久7777| 久久er热视频在这里精品| 色偷偷88888欧美精品久久久| 久久国产成人精品国产成人亚洲| 久久国产精品成人片免费| 一本色道久久综合狠狠躁篇 | 国产农村妇女毛片精品久久| 人妻无码久久一区二区三区免费| 精品久久久久久99人妻| 亚洲综合精品香蕉久久网97| 99久久99这里只有免费费精品| 久久精品国产亚洲AV蜜臀色欲 | 久久久久国产精品三级网| 999久久久无码国产精品| 亚洲国产精品成人久久| 久久99精品国产麻豆宅宅| 久久精品国产亚洲av瑜伽| 久久国产成人午夜AV影院|