delphi 实现SOCKS5代理(客户端),那位老兄能给个代码,要求代理客户端运行后,所有的网络连接到要经过SOCKS5代理。

解决方案 »

  1.   

    不是太明楼上兄弟的意思,你是想用Socket协议 通讯是吗?在广域网上运行。
      

  2.   

    做socks5代理服务端的话就方便了,客户端还真没研究过
      

  3.   

    SOCKS5代理客户端,已经做好了,也是从网上下的代码,拿来修改,你们去GOOGLE一下就知道了,我吧把代码贴上来吧。
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls,winsock;
    const
        SOCKS_VER5=$05;    AUTH_NO=$00   ;//no authentication required
        AUTH_REQU=$02   ;//method=0x02: username/password    CMD_CONNECT=$01   ;
        RSV_DEFAULT=$00  ;
        ATYP_DN=$03     ;
        REP_SUCCESS=$00;
        ATYP_IPV4=$01;type
      TFormSocks = class(TForm)
        GroupBox1: TGroupBox;
        Edit1: TEdit;
        Label1: TLabel;
        Label2: TLabel;
        Edit2: TEdit;
        CheckBox1: TCheckBox;
        Label3: TLabel;
        Edit3: TEdit;
        Label4: TLabel;
        Edit4: TEdit;
        btnConnect: TButton;
        Memo1: TMemo;
        Label5: TLabel;
        Label6: TLabel;
        Edit5: TEdit;
        Label7: TLabel;
        Edit6: TEdit;
        procedure FormCreate(Sender: TObject);
        procedure FormShow(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure btnConnectClick(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
        function socksconnect(skt:TSocket;target:TSockAddr):boolean;
        function Auth(skt:tsocket;bauth:byte):boolean;
      end;var
      FormSocks: TFormSocks;implementation{$R *.DFM}procedure TFormSocks.FormCreate(Sender: TObject);
    begin
        //update view
        Memo1.Lines.Clear;
        Edit1.Text:='10.10.2.51';
        Edit2.Text:='1080';
        Edit3.Text:='10.12.13.66';
        Edit4.Text:='23';
     //   Edit5.Text:='';
     //   Edit6.Text:='';
        Edit6.PasswordChar:='*';
    end;procedure TFormSocks.FormShow(Sender: TObject);
    var
        WSAData:TWSAData;
    begin
        //init Socket
        if (WSAStartup(MAKEWORD(2,0),WSAData)<>0) then
        begin
            //初始化失败
            Memo1.lines.add('Init Failed');
            exit;
        end
        else
            Memo1.lines.add('Init Success');
    end;procedure TFormSocks.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
         //release winsock
         WSACleanUP();
    end;procedure TFormSocks.btnConnectClick(Sender: TObject);
    var
        clisock:TSocket;
        tarsocksrv:TSockAddr;
        saproxy:TSockAddr;
        pSocksAddr:PChar;
        Re:integer;
        ErrCode:Integer;
        AuthSucc:boolean;
        ConSucc:boolean;
    begin
        //1.create a client socket
        Memo1.Lines.Add('Creating a socket');
        clisock:=socket(AF_INET,SOCK_STREAM,0);
        //valid check
        if(clisock=INVALID_SOCKET) then
            begin
                Memo1.lines.Add('Error on create socket');
                Exit;
            end;
        Memo1.Lines.add('Success on create socket');
        //2.connect to socks5 server
        Memo1.lines.Add('Connecting to socks server');
        ZeroMemory(@saproxy,sizeof(saproxy));
        saproxy.sin_family := AF_INET;
        //set proxy infomation
        GetMem(pSocksAddr,Length(Edit1.Text)+1);
        ZeroMemory(pSocksAddr,Length(Edit1.Text)+1);
        StrPCopy(pSocksAddr,Edit1.Text);
        saproxy.sin_addr.S_addr :=inet_addr(pSocksAddr);
        FreeMem(pSocksAddr);
        saproxy.sin_port := htons(strtoint(Edit2.Text));
        Re:=connect(clisock,saproxy,sizeof(saproxy));
        if Re = SOCKET_ERROR then
            begin
                ErrCode:=WSAGetLastError();
                Memo1.Lines.Add('Err on Connect to socks5 Errcode:'
                                +IntToStr(ErrCode));
                Exit;
            end;
        Memo1.Lines.Add('Connect to socks5 server success');
        //3.prepare Auth
        Memo1.Lines.Add('Enter Auth');
        if CheckBox1.Checked then
            AuthSucc:=Auth(clisock,AUTH_REQU)
        else
            AuthSucc:=Auth(clisock,AUTH_NO);
        if not AuthSucc then
            begin
                Memo1.Lines.Add('Auth Failed');
                Memo1.Lines.Add('Close socket');
                CloseSocket(clisock);
                Exit;
            end;
        Memo1.Lines.Add('Auth finish');
        //4. link to target
        Memo1.Lines.Add('Link to target ip');
        ZeroMemory(@tarsocksrv,Sizeof(tarsocksrv));
        //prepare
        Getmem(psocksaddr,length(edit3.text)+1);
        zeromemory(psocksaddr,length(edit3.text)+1);
        strpcopy(psocksaddr,edit3.text);
        tarsocksrv.sin_addr.s_addr := inet_addr(pSocksAddr);
        tarsocksrv.sin_port := htons(strtoint(edit4.text));
        tarsocksrv.sin_family := AF_INET;
        //connect
        consucc:=socksconnect(clisock,tarsocksrv);
        if consucc then
            memo1.Lines.Add('conncct succ')
        else
            memo1.Lines.add('failed');
        //5 use this socket pipe to communicat
        //recv(clisock,buf,127,0);
        //close socket
        Memo1.lines.Add('Closing socket');
        Re:= closesocket(clisock);    //shutdown(clisock,SD_BOTH);
    end;function TFormSocks.socksconnect(skt: TSocket; target: TSockAddr): boolean;
    var
        buf:array[0..1023]of byte;
        re:integer;
    begin
        //preapre
    buf[0] := SOCKS_VER5;
    buf[1] := CMD_CONNECT;
    buf[2] := RSV_DEFAULT;
    buf[3] := ATYP_IPV4;
        //copy data
        copymemory(@buf[4],@target.sin_addr,4);
        copymemory(@buf[8],@target.sin_port,2);
        //communicate
        re:=send(skt,buf,10,0);
        if re=-1 then
            begin
                result:= false;
                exit;
            end;
        re :=recv(skt,buf,1024,0);
        if re=-1 then
            begin
                result:=false;
                exit;
            end;
        if buf[1]<>REP_SUCCESS then
            begin
                result:=false;
                exit;
            end;
        result:=true;
    end;
      

  4.   

    //接上
    function TFormSocks.Auth(skt: tsocket; bauth: byte): boolean;
    var
        buf:array[0..256]of byte;
        re:integer;
        i:integer;
        usr:pchar;
        pwd:pchar;
    begin
        getmem(usr, length(edit5.text)+1);
        zeromemory(usr, length(edit5.text)+1);
        strpcopy(usr,edit5.text);    getmem(pwd, length(edit6.text)+1);
        zeromemory(pwd, length(edit6.text)+1);
        strpcopy(pwd,edit6.text);
        case bauth of
          AUTH_NO:
                  begin
                        buf[0] := SOCKS_VER5;
                buf[1] := $01;
                buf[2] := $00;
                re := send(skt, buf, 3, 0);
                        if re=-1 then
                            begin
                                result:=false;
                                exit;
                            end;
                        re:=recv(skt,buf,257,0);
                        if re<2 then
                            begin
                                result:=false;
                                exit;
                            end;
                        if buf[1]<>AUTH_NO then
                            begin
                                result:=false;
                                exit;
                            end;
                        result:=true;
                  end;
          AUTH_REQU:
                    begin
                 buf[0] := SOCKS_VER5;
                 buf[1] := $02;
                 buf[2] := $00;
                 buf[3] := $02;
                 re := send(skt, buf, 4, 0);
                 if (re=-1)then
                            begin
                                result:=false;
                                exit;
                            end;
                        ZeroMemory(@buf,257);
                 re := recv(skt, buf, 257, 0);
                 if (re < 2) then
                            begin
                                result:=false;
                                exit;
                            end;
                 if (buf[1] <> AUTH_REQU) then
                            begin
                                result:=false;
                                exit;
                             end;
                        zeromemory(@buf,257);             buf[0] := $01; //current version of subnegotiation
                 buf[1] := length(edit5.text); //length of username
                 for i:=0 to buf[1]-1 do
                            buf[2+i]:=ord(usr[i]);
                    buf[2+length(edit5.text)]:=length(edit6.text);
                 for i:=0 to buf[2+length(edit5.text)]-1 do
                            buf[3+length(edit5.text)+i]:=ord(pwd[i]);
                 re := send(skt, buf,length(edit5.text)+length(edit6.text)+3,0);
                 if (re=-1) then
                            begin
                                result:=false;
                                exit;
                            end;
                 re := recv(skt, buf, 257, 0);
                 if (buf[1] <> $00) then
                            begin
                                result:=FALSE;
                                exit;
                            end;
                     result:= TRUE;
                    end;       else
                result:=false;
          end;    freemem(usr);
        freemem(pwd);
    end;end.
    这代码可以运行,但是不能总是每次都要动手输入目标地址和目标端口吧??
      

  5.   

    有关SOCKET的连接程序我也写出来了,也可透过账号密码验证了。
    但是正在烦恼如何制作类似像SocksCap的功能,让别的程序也可以透过这个代理客户端?不知道这个方法你研究出来了吗?