• <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>

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運(yùn)轉(zhuǎn),開心的工作
            簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
            有很多公司不能直接和Internet相連,必須通過代理和www連接,瀏覽、下載資料。
            代理服務(wù)器支持的協(xié)議也有所不同,有支持Sock、HTTP代理的這樣我們做的客戶端軟件就需要支持這些代理,使用戶能夠通過這些代理透過防火墻和外網(wǎng)相連,一般Sock分為Sock4和Sock5,這里我們只實現(xiàn)Sock5協(xié)議。
            RFC1928描述了Socks協(xié)議的細(xì)節(jié),告訴我們客戶程序如何同Socks代理協(xié)商,取得透過該協(xié)議對外傳輸?shù)耐緩?。英文的URL為:http://www.ietf.org/rfc/rfc1928.txt,建議先了解以上鏈接內(nèi)容后在閱讀下文。另外給大家推薦學(xué)習(xí)協(xié)議的好地方:http://www.cnpaf.com中國協(xié)議分析網(wǎng),有很多好東東,可以去看看。
            下面說明一下實現(xiàn)的方法。
            代理的實現(xiàn)方法實際就是Socket編程,只要通訊時遵循它們的協(xié)議就可以。首先理解它們的協(xié)議是關(guān)鍵。
            示意圖:

            1.1??? Sock5協(xié)議實現(xiàn)

            1.1.1??????? Sock5協(xié)議內(nèi)容

            1.? 客戶端首先要與代理服務(wù)器連接,連接后要向代理發(fā)送版本號、認(rèn)證方法、方法選擇格式如下:
            版本號(1字節(jié)) |? 供選擇的認(rèn)證方法(1字節(jié)) ?|? 方法序列(1-255個字節(jié)長度)
            如果你支持的版本為SOCK5那么版本號就為0x05;可供選擇的方法是指你的協(xié)議支持幾種認(rèn)證方式,因為我們實現(xiàn)只支持一種所以就填0x01,如果你是兩種就寫0x02;認(rèn)證方法序列包括(0x00為不需認(rèn)證、0x02為需要用戶名和密碼認(rèn)證,通常是這兩種,如果想了解更多請參看Rfc1928)。
            這樣組合你的報文應(yīng)該為:0x05 0x01 0x00
            如果需要認(rèn)證那么為:0x05 0x01 0x02
            2.? 代理接收到客戶端的請求,會向客戶端返回信息,格式為:
            版本號 | 服務(wù)器選定的方法
            如果服務(wù)器支持驗證方式,返回的報文為:
            0x05 0x02
            3.? 接下來根據(jù)服務(wù)器的驗證方式,發(fā)送驗證信息了,報文格式為:
            0x01 | 用戶名長度(1字節(jié))| 用戶名(長度根據(jù)用戶名長度域指定) | 口令長度(1字節(jié)) | 口令(長度由口令長度域指定)
            4.? 服務(wù)器接收信息后進(jìn)行驗證,返回如下格式:
            0x01 | 驗證結(jié)果標(biāo)志
            驗證結(jié)果標(biāo)志:0x00表示驗證成功,其他值均為錯誤碼

            1.1.2??????? Sock5協(xié)議實現(xiàn)

            根據(jù)上面所述的步驟和協(xié)議內(nèi)容,就可以實現(xiàn)SOCK5代理了。下面我給出我寫的實現(xiàn)SOCKT5代理的函數(shù)代碼和注釋,供參考(delphi6+win2K+sp4調(diào)試通過,代理服務(wù)器用的是CCProxy6.0)
            function?TBZSock5ProxyApi.SetProxy(ASocket:?Pointer):?Integer;
            var
            ??proxyUser,?proxyPwd:?String;
            ??bIsValid:?Boolean;
            ??sock:?
            ^ TSocket;
            ??sockServer:?TSockAddrIn;
            ??command:?array?[
            0 .. 9 ]?of?Byte;
            ??re,?len,?ulen,?plen:?Integer;
            // ??buffer:?PByte;
            ??buffer:?array?[ 0 .. 1023 ]?of?Byte;
            begin
            ??sock?:
            = ?ASocket;
            ??
            if ?FProxyParam.GetServer? = ? '' ?then
            ??begin
            ????Result?:
            = ? 0 ;
            ????Exit;
            ??end
            ??
            else
            ??begin
            ????Result?:
            = ? 0 ;
            ????sock
            ^ ?: = ?socket(AF_INET,?SOCK_STREAM,? 0 );
            ????
            if ?sock ^ ? = ?INVALID_SOCKET?then
            ????begin
            ??????Result?:
            = ? 1 ;
            ??????Exit;
            ????end;
            ?
            ????sockServer.sin_family?:
            = ?AF_INET;
            ????sockServer.sin_port?:
            = ?htons(FProxyParam.GetPort);???? // 將整形數(shù)變?yōu)榫W(wǎng)絡(luò)字節(jié)流
            ????sockServer.sin_addr.S_addr?: = ?inet_addr(PChar(FProxyParam.GetServer));
            ?
            ????
            // 連接遠(yuǎn)程主機(jī)
            ???? if ?WinSock.connect(sock ^ ,?sockServer,?SizeOf(sockServer))? <> ? 0 ?then
            ????begin
            ??????Result?:
            = ? 1 ;
            ??????Exit;
            ????end;
            ?
            ????bIsValid?:
            = ?FProxyParam.GetProxyValid;
            ?
            ????
            // 發(fā)送SOCK5協(xié)議指令
            ????FillChar(command,? 10 ,? 0 );
            ????command[
            0 ]?: = ? 5 ;
            ????
            if ?bIsValid?then
            ??????command[
            1 ]?: = ? 2
            ????
            else
            ??????command[
            1 ]?: = ? 1 ;
            ????
            if ?bIsValid?then
            ??????command[
            2 ]?: = ? 2
            ????
            else
            ??????command[
            2 ]?: = ? 0 ;
            ?
            ????
            // 發(fā)送登陸指令
            ???? if ?bIsValid?then
            ??????re?:
            = ?WinSock.send(sock ^ ,?command,? 4 ,? 0 )
            ????
            else
            ??????re?:
            = ?WinSock.send(sock ^ ,?command,? 3 ,? 0 );
            ????
            if ?re? = ?SOCKET_ERROR?then
            ????begin
            ??????Result?:
            = ? 1 ;
            ??????Exit;
            ????end;
            ?
            ????
            // 接收返回的消息
            ????fillchar(command,? 10 ,? 0 );????????????????????????? // 接收前用0再次填充
            ????re?: = ?WinSock.recv(sock ^ ,?command,? 2 ,? 0 );
            ????
            if ?re? <> ? 2 ?then
            ????begin
            ??????Result?:
            = ? 1 ;
            ??????Exit;
            ????end;
            ????
            if ?command[ 1 ] = $FF?then
            ????begin
            ??????Result?:
            = ? 1 ;
            ??????Exit;
            ????end;
            ?
            ????
            if ?(not?bIsValid)?and?(command[ 1 ] = 0 )?then
            ????begin
            ??????Exit;
            ????end;
            ?
            ????proxyUser?:
            = ?FProxyParam.GetUsername;
            ????proxyPwd?:
            = ?FProxyParam.GetPassword;
            ?
            ????
            if ?command[ 1 ]? <> ? 0 ?then
            ????begin
            ??????
            if ?command[ 1 ]? <> ? 2 ?then
            ??????begin
            ????????Result?:
            = ? 1 ;
            ????????Exit;
            ??????end;
            ??????
            if ?bIsValid?then
            ??????begin
            ????????ulen?:
            = ?Length(proxyUser);
            ????????plen?:
            = ?Length(proxyPwd);
            ????????len?:
            = ? 3 ? + ?ulen? + ?plen;
            ????????fillchar(buffer,?
            1024 ,? 0 );
            ?
            ????????buffer[
            0 ]?: = ? 5 ;
            ????????buffer[
            1 ]?: = ?ulen;
            ????????StrPCopy(@buffer[
            2 ],?proxyuser);
            ????????buffer[
            2 ? + ?ulen]?: = ?plen;
            ????????StrPCopy(@buffer[
            2 ? + ?ulen? + ? 1 ],?proxyPwd);
            ?
            ????????
            // 發(fā)送驗證信息
            ????????re?: = ?send(sock ^ ,?buffer,?len,? 0 );
            ????????
            if ?re? = ?SOCKET_ERROR?then
            ????????begin
            ??????????Result?:
            = ? 1 ;
            ??????????Exit;
            ????????end;
            ?
            ????????
            // 接收驗證返回信息
            ????????fillchar(command,? 10 ,? 0 );
            ????????re?:
            = ?recv(sock ^ ,?command,? 2 ,? 0 );
            ????????
            if ?((re <> 2 )?or?((command[ 0 ] <> 1 )?and?(command[ 1 ] <> 0 ?)))?then
            ????????begin
            ??????????Result?:
            = ? 1 ;
            ??????????Exit;
            ????????end;
            ??????end???
            // if?bisValid
            ?????? else
            ??????begin
            ????????Result?:
            = ? 1 ;
            ????????Exit;
            ??????end;?????????????????????
            //
            ????end;? // ?if?command[1]<>0
            ??end;?? // end?first?if
            ?
            end;
            上面的函數(shù)中有一個FproxyParam變量,它是代理參數(shù)的值對象,聲明如下:
            ??TProxyParam?
            = ? class
            ??
            private
            ????FUsername,????????
            // 代理驗證用戶名
            ????FPassword,???????? // 代理驗證密碼
            ????FServer:?String;???? // 代理服務(wù)器地址
            ????FPort:?Integer;????? // 代理服務(wù)器端口號
            ????FIsValid:?Boolean;?? // 是否驗證?????如果代理服務(wù)器是驗證的,那么此值應(yīng)該為true
            ?
            ????procedure?Clear;
            ??
            public
            ????constructor?Create;
            ????procedure?SetUsername(AUsername:?String);
            ????procedure?SetPassword(APassword:?String);
            ????procedure?SetServer(AServer:?String);
            ????procedure?SetPort(APort:?Integer);
            ????procedure?SetProxyValid(AValid:?Boolean);
            ?
            ????function?GetUsername:?String;
            ????function?GetPassword:?String;
            ????function?GetServer:?String;
            ????function?GetPort:?Integer;
            ????function?GetProxyValid:?Boolean;
            ??end;
            使用此函數(shù):
            假設(shè)已經(jīng)創(chuàng)建了一個ClientSocket1(TclientSocket對象),它的IP和Port設(shè)置為代理服務(wù)器的IP和Port,那么就有下面的代碼:
            ......
            Var
            Re:Integer;
            Begin
            Re:
            = SetProxy(@(ClientSocket.Socket.SocketHandle))?;?? // 如果驗證成功,那么就可以用返回的//socket進(jìn)行相應(yīng)的通訊
            If?Re = 0 ?then?
            Begn
            ??ShowMessage(‘Sock5?is?ok’);?????????
            // 代理服務(wù)器就會有連接的數(shù)據(jù)流顯示
            End
            Else?begin
            ??ShowMessage(‘Sock5?is?error’);
            End;
            End;
            ……
            上面的例子如果設(shè)置代理成功,那么代理服務(wù)器就會有連接的數(shù)據(jù)流顯示。表示與代理服務(wù)器有數(shù)據(jù)交換,如果沒有成功則務(wù)數(shù)據(jù)流顯示。
            ?
            ?
            ?????????????????????????????????????????????????????????????? 李孟巖
            ????????????????????????????????????????????????????????????????????? mengyan_yl@sohu.com
            ??????????????????????????????????????????????????????????????????????????????????? 2005-07-05實現(xiàn)Sock5代理
            久久久久青草线蕉综合超碰| 久久久久久国产精品美女| 久久人人爽人人爽人人片AV不| 久久久久久曰本AV免费免费| 久久国产精品99国产精| 品成人欧美大片久久国产欧美...| 亚洲人成网站999久久久综合 | 国内精品久久久久久久涩爱| 日日狠狠久久偷偷色综合免费| 午夜精品久久久久久中宇| 欧美亚洲另类久久综合| 超级97碰碰碰碰久久久久最新| 久久亚洲私人国产精品| 久久久久久国产精品免费免费| 性做久久久久久久| 久久精品国产亚洲一区二区三区| 亚洲精品蜜桃久久久久久| 久久国产成人午夜aⅴ影院| 国产成年无码久久久免费| 国产AV影片久久久久久| 亚洲av日韩精品久久久久久a| 国产成人久久久精品二区三区| 国产精品中文久久久久久久| 久久伊人精品青青草原高清| 久久精品免费全国观看国产| 99久久精品久久久久久清纯| 久久精品国产亚洲AV久| 久久精品国产第一区二区| 99久久精品午夜一区二区| 久久亚洲AV无码精品色午夜| 大美女久久久久久j久久| 久久婷婷成人综合色综合| 日韩欧美亚洲综合久久影院Ds | 国产无套内射久久久国产| 国产69精品久久久久9999APGF| 久久精品成人免费国产片小草| 久久亚洲欧美国产精品| 无码国内精品久久综合88 | 国产福利电影一区二区三区久久久久成人精品综合 | 国产精品内射久久久久欢欢| 久久久国产精品亚洲一区|