IndyFTP解决方法:一个TidFTP,一个TIOHandlerSocket,一个TsocksInfo,
通过属性连接起来,就是IdFTp1.IOhandler:=idIOhanlderSocket1;
idIohandlerSocket1.SocksInfo:=idSocksInfo1的意思,不必写代码的,
设置好SocksInfo的版本为Socks5,Host为代理的IP或Domain Name,Port为代理的端口,就可以让IndyFTp通过协议为Socks5的代理服务器(防火墙)连接了,当然别忘记设置好IdFTp的ProxySettings的ProxyType哦,还有其他的,关于User@站点的是要根据你的代理服务器(防火墙)的支持协议而定,一般有好几种的:Open FTP-Host:FTP-Port
SITE FTP-Host FTP-Port
SITE FTP-Host:FTP-Port
SITE FTP-User@FTP-Host FTP_port
SITE FTP-User@FTP-Host:FTP_port
USER FTP-User@FTP-Host FTP-Port
USER FTP-User@FTP-Host:FTP-Port
USER FTP-User@FTP-Host Proxy-User
USER Proxy-User@FTP-Host
CheckPoint Firewall:USER FTP-User@Proxy-User@FTP-Host / PASS pass@firewallpass
Indy只支持其中的几种,其他的自己添加。
看不懂?那是通过SendCmd的底层命令发送联接指令给代理服务器,由代理服务器解释以后,建立到外部FTP服务器的连接,因为你是不能直接连接到外部FTP的,记得就是这时一定要用Passive模式,因为你在防火墙之后,只有你可以主动访问外部,而外部不可以主动访问你,关于HTTP Proxy是怎样呢?也是差不多,就是复杂些:建立HTTP连接,通过SendCmd的底层命令发送Connect FTP:Port HTTP/1.0<CR>User-Agent: Mozilla/4.0 (compatible; LY FTP Explorer)<CR>Proxy-Connection: Keep-Alive<CR><CR>等Http信息,<CR>是回车+换行,不管通过那一种连接,连接建立以后直接发送FTP命令就可以了,注意List和上传/下载(stor/retr)的时候会建立新的连接,这时候也要用上述方法建立,否者无法成功建立新的数据端口,SendCMD是Indy的通用命令,用于发送原始的TCP数据(ASCII码的),从这里下载Indy9.0.10: http://www.nevrona.com/indy/ 还有就是Indy本身就有很多的bug,我搞了半年才修正了不少,这个最新的也有不少噢,很对不起我不能提供修正版和完整的Proxy解决办法的源代码给各位,请大家见凉。
下面是Indy9.0.10修正版的片段代码:
// added by Liu Yang 2002.2.1
fpcmSiteHostPort: // Send command SITE (FTP-Host FTP-Port)
begin
if (Length(ProxySettings.UserName)>0) then begin
if SendCmd('USER ' + ProxySettings.UserName, [230, 331]) = 331 then begin
SendCmd('PASS ' + ProxySettings.Password, 230);
end; // 230是允许的FTP协议返回代码,
//详细的看RFC 959 http://www.rfc-editor.org/rfc/rfc959.txt
end;//proxy login
SendCmd('SITE '+FHost+' '+IntToStr(FPort));//? Server Reply? 220?
if SendCmd('USER ' + FUserName, [230, 331]) = 331 then begin
SendCmd('PASS ' + FPassword, 230);
end;
end; //fpcmSiteHostPort
。。。。
fpcmUserPass: //USER user@firewalluser@hostname / PASS pass@firewallpass
begin // check point firewall / added port by Liu Yang 2002.2.2
if SendCmd(Format('USER %s@%s@%s %d',[FUserName,ProxySettings.UserName,FHost,FPort]), [230, 331])=331 then begin
if Length(ProxySettings.Password)>0 then begin
SendCmd('PASS '+FPassword+'@'+ProxySettings.Password, 230);
end
else begin
SendCmd('PASS '+FPassword, 230);
end;//if @
end;
end;//fpcmUserPass
。。。。。。
procedure TIdFTP.Connect(AAutoLogin: boolean = True);
var
TmpHost: String;
TmpPort: Integer;
begin
try
//APR 011216: proxy support
TmpHost:=FHost;
TmpPort:=FPort;
try
if (ProxySettings.ProxyType>fpcmNone) and (Length(ProxySettings.Host)>0) then begin
FHost:=ProxySettings.Host;
FPort:=ProxySettings.Port;
end;
inherited Connect;
finally
FHost:=TmpHost;
FPort:=TmpPort;
end;//tryf
// fixed by Liu Yang 2002.2.1
if ProxySettings.ProxyType=fpcmNone then
begin // non-proxy connection
GetResponse([220]);
Greeting.Assign(LastCmdResult);
end else InputBuffer.Clear; // clear buffer for using proxy to connect
if AAutoLogin then begin
Login;
DoAfterLogin;
SendTransferType;
// OpenVMS 7.1 replies with 200 instead of 215 - What does the RFC say about this?
// Fix by Liu Yang 2002.6.9 for support Cisco FTP Server (It will reply 502)
if SendCmd('SYST', [200, 215, 500, 502]) = 500 then begin
FSystemDesc := RSFTPUnknownHost;
end else begin
FSystemDesc := LastCmdResult.Text[0];
end;
DoStatus(ftpReady);
end;
except
Disconnect;
raise;
end;
end;