delphi网络编程soket5代码分析!
program Test;{$APPTYPE CONSOLE}//这是个控制台程序。
uses
Windows,
Messages,
SysUtils,
Classes,
Controls,
StdCtrls,
winsock;
const //声明常量。
SOCKS_VER5=$05;
AUTH_NO=$00;//no authentication required
AUTH_REQU=$02;//需要用户名和密码。
CMD_CONNECT=$01;
RSV_DEFAULT=$00;
ATYP_DN=$03;
REP_SUCCESS=$00;
ATYP_IPV4=$01;
type//定义类。
Tclient=class//继承Tobject类。
procedure initwinscok();
procedure btnConnectClick();//测试按钮事件函数。
public
function socksconnect(skt:TSocket;target:TSockAddr):boolean;//与服务器协商函数。
function Auth(skt:tsocket;bauth:byte):boolean;//验证函数。
end;
var//声明全局变量。
client:Tclient;
socks_IP:String='192.168.0.30';
socks_Port: String='1080';
Local_IP:String='192.168.0.30';
Local_Port:String='1080';
UseName:String='admin';
UsePassword:String='123456';
//实现Tclient类中的方法。
//***************************************************/
procedure Tclient.initwinscok;
var
WSAData:TWSAData;
begin
if (WSAStartup(MAKEWORD(2,0),WSAData)<>0) then
begin
writeln('函数初始化成功!');
exit;//初始化失败
end
end;
//*******************************************************/
procedure Tclient.btnConnectClick();
var
clisock:TSocket;
tarsocksrv:TSockAddr;
saproxy:TSockAddr;
pSocksAddr:PChar;
Re:integer;
ErrCode:Integer;
AuthSucc:boolean;
ConSucc:boolean;
begin
clisock:=socket(AF_INET,SOCK_STREAM,0);
if(clisock=INVALID_SOCKET) then
begin
Exit;
end;
ZeroMemory(@saproxy,sizeof(saproxy));
saproxy.sin_family := AF_INET;
GetMem(pSocksAddr,Length(socks_IP)+1);
ZeroMemory(pSocksAddr,Length(socks_IP)+1);
StrPCopy(pSocksAddr,socks_IP);
saproxy.sin_addr.S_addr :=inet_addr(pSocksAddr);
FreeMem(pSocksAddr);
saproxy.sin_port := htons(strtoint(socks_Port));
Re:=connect(clisock,saproxy,sizeof(saproxy));
if Re = SOCKET_ERROR then
begin
ErrCode:=WSAGetLastError();
Exit;
end;
if not AuthSucc then
begin
CloseSocket(clisock);
Exit;
end;
ZeroMemory(@tarsocksrv,Sizeof(tarsocksrv));
Getmem(psocksaddr,length(Local_IP)+1);
zeromemory(psocksaddr,length(Local_IP)+1);
strpcopy(psocksaddr,Local_IP);
tarsocksrv.sin_addr.s_addr := inet_addr(pSocksAddr);
tarsocksrv.sin_port := htons(strtoint(Local_Port));
tarsocksrv.sin_family := AF_INET;
consucc:=socksconnect(clisock,tarsocksrv);
Re:= closesocket(clisock);
end;
//****************************************************
function Tclient.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;
//****************************************************
function Tclient.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(UseName)+1);
zeromemory(usr, length(UseName)+1);
strpcopy(usr,UseName);
getmem(pwd, length(UsePassword)+1);
zeromemory(pwd, length(UsePassword)+1);
strpcopy(pwd,UsePassword);
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(UseName); //length of username
for i:=0 to buf[1]-1 do
buf[2+i]:=ord(usr[i]);
buf[2+length(UseName)]:=length(UsePassword);
for i:=0 to buf[2+length(UseName)]-1 do
buf[3+length(UseName)+i]:=ord(pwd[i]);
re := send(skt, buf,length(UseName)+length(UsePassword)+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;
//****************************************************
begin
client:=Tclient.create;
writeln('创建client对象成功!');
client.initwinscok();
writeln('调用initwinscok方法成功!');
client.btnConnectClick();
writeln('调用btnConnectClick方法成功!');
readln; //锁定控制台窗口,
end.
这代码怎么样才能连接上代理服务器,需要怎么样修改?
还有帮忙解释下,TTCPClient同步异步。