
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;