用TServerSocket和TClientSocket能否通过proxy建立连接传送文件?(200分)

  • 主题发起人 主题发起人 loyalfox
  • 开始时间 开始时间
L

loyalfox

Unregistered / Unconfirmed
GUEST, unregistred user!
用TServerSocket和TClientSocket传送文件的时候,如果我要传送文件的机器是通过代理
上网的,怎么编写程序也通过代理,使得TServerSocket和TClientSocket之间能传送文件?
就好象利用ftp控件上传文件,可以通过本地代理服务器与远程服务器端建立连接,再说它
本身有proxy属性,如果是TServerSocket和TClientSocket,通过代理上网他们之间怎么建
立连接?

请大侠指教!
 
用indy 广播就行了!
 
用indy 广播?那传送文件怎么传啊?还得通过TServerSocket和TClientSocket,利用socket
传输,还得需要建立连接的吗~!该怎么解决啊?
 
没有任何问题,只要熟悉SOCK5协议就行了,用UDP发文件不安全哦
 
我的实践经验:
TServerSocket和TClientSocket只要是TServerSocket具有合法的IP地址(即在internet的唯一IP上),
而TClientSocket通过的是内部局域网(例如,网通)经过NAT转换上的internet网,那么在写代码的时候
根本就用不着考虑什么代理服务器。
如果一定要通过代理服务器,那么就用sock5协议,随便找本网络编程的书就有例程。
 
TClientSocket怎样解决加入代理功能呢。
 
这里有解决方法:
http://www.delphibbs.com/delphibbs/DispQ.asp?LID=2019869
下面的是lich在上面回答的问题。
---------------------------------------------------------
我也没有找到能像SocketClient的能阻塞工作的Socket对象,
只好自己实现代理协议了,我修改了SConnect.pas文件,
加入了免费Socks5代理的支持,主要进行了以下几处修改

将SConnect.pas 复制到程序目录下

1.
在 TSocketConnection 的 published 部分加入
property Socks5Addr: String read FSocks5Addr write FSocks5Addr;
property Socks5Port: Integer read FSocks5Port write FSocks5Port;
然后按 Ctrl + Shift + C 进行代码自动完成
2.
在 TSocketTransport 的 public 部分加入
property SocksAddr: String read FSocksAddr write FSocksAddr;
property SocksPort: Integer read FSocksPort write FSocksPort;
然后按 Ctrl + Shift + C 进行代码自动完成

3.
在 TSocketConnection.CreateTransport 方法的最后一句代码
Result := SocketTransport as ITransport;
前面加上:
SocketTransport.SocksAddr := Socks5Addr;
SocketTransport.SocksPort := Socks5Port;

4.
修改 TSocketTransport.SetConnected 方法,修改后如下所示:
procedure TSocketTransport.SetConnected(Value: Boolean);
var
Buff: array[1..500] of Char;
Len, t: Integer;
IsFail: Boolean;
saddr: String;
begin
if GetConnected = Value then Exit;
if Value then
begin
if (FAddress = '') and (FHost = '') then
raise ESocketConnectionError.CreateRes(@SNoAddress);
FClientSocket := TClientSocket.Create(nil);
FClientSocket.ClientType := ctBlocking;
FSocket := FClientSocket.Socket;
if Trim(FSocksAddr) = '' then
begin
FClientSocket.Port := FPort;
if FAddress <> '' then
FClientSocket.Address := FAddress else
FClientSocket.Host := FHost;
FClientSocket.Open;
end
else
begin
//使用代理服务器的端口进行连接
FClientSocket.Port := FSocksPort;
//使用代理服务器的地址进行连接
FClientSocket.Host := FSocksAddr;
if FAddress = '' then saddr := FHost else saddr := FAddress;
FClientSocket.Open;
//传递协议数据
if FSocket.Connected then
begin
//请求使用不需要验证的Socks5代理
Buff[1] := #5;
Buff[2] := #1;
Buff[3] := #0;
FSocket.SendBuf(Buff, 3);
Len := FSocket.ReceiveBuf(Buff, 2);
IsFail := not ((Len = 2) and (Buff[1] = #5) and (Buff[2] = #0));
if not IsFail then
begin
//发送连接远程主机的命令
Buff[1] := #5;
Buff[2] := #1;
Buff[3] := #0;
Buff[4] := #3;
//设置主机名长度
Buff[5] := Chr(Length(saddr));
//复制主机名
Move(saddr[1], Buff[6], Ord(Buff[5]));
//计算端口的位置
t := 5 + Ord(Buff[5]) + 1;
//设置目标端口参数
Buff[t] := Chr((FPort shr 8) and $ff);
Buff[t + 1] := Chr(FPort and $ff);
FSocket.SendBuf(Buff, t + 1);
Len := FSocket.ReceiveBuf(Buff, 5);
//验证是否连接成功
IsFail := not ((Len = 5) and (Buff[1] = #5) and (Buff[2] = #0));
if not IsFail then
begin
if Buff[4] = #1 then
t := 5
else
t := Ord(Buff[5]) + 2;
Len := FSocket.ReceiveBuf(Buff[6], t);
IsFail := not (Len = t);
end;
end;
if IsFail then
begin
raise Exception.Create('connect via proxy fail.');
end;
end;
end;
end else
begin
FSocket.Close;
FClientSocket.Free;
if FEvent <> 0 then WSACloseEvent(FEvent);
end;
end;

这样,当TSocketConnection.Socks5Addr 不为空时,会自动使用Socks5代理连接
我仅仅实现了免费代理的连接方法,
其他的连接方法请参照Socks的 RFC 文档 rfc1928.txt

http://archive.socks.permeo.com/rfc/rfc1928.txt
http://archive.socks.permeo.com/rfc/rfc1929.txt

如果想索取我修改的源代码,请发信到 mastercn@163.com
 
后退
顶部