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); //将整形数变为网络字节流 sockServer.sin_addr.S_addr := inet_addr(PChar(FProxyParam.GetServer)); //连接远程主机 if WinSock.connect(sock^, sockServer, SizeOf(sockServer)) <>0 then begin Result :=1; Exit; end; bIsValid := FProxyParam.GetProxyValid; //发送SOCK5协议指令 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; //发送登陆指令 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); //发送验证信息 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; 上面的函数中有一个FproxyParam变量,它是代理参数的值对象,声明如下: TProxyParam =class private FUsername, //代理验证用户名 FPassword, //代理验证密码 FServer: String; //代理服务器地址 FPort: Integer; //代理服务器端口号 FIsValid: Boolean; //是否验证 如果代理服务器是验证的,那么此值应该为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;
...... Var Re:Integer; Begin Re:=SetProxy(@(ClientSocket.Socket.SocketHandle)) ; //如果验证成功,那么就可以用返回的//socket进行相应的通讯 If Re=0 then Begn ShowMessage(‘Sock5 is ok’); //代理服务器就会有连接的数据流显示 End Else begin ShowMessage(‘Sock5 is error’); End; End; ……