Chilkat FTP传输报错425:无法建立TLS数据连接求助
FTP over TLS传输错误:425 Unable to build data connection TLS session of data connection not resumed
我使用Chilkat库实现FTP文件传输时,遇到错误:error 425 Unable to build data connection TLS session of data connection not resumed。相同的FTP操作在FileZilla客户端中可正常执行,但用Chilkat代码实现时,远程文件szRemoteFile1虽被创建但内容为空,请求技术解决。
问题代码
if (!CkGlob.UnlockBundle(BUNDLE_CHILKAT)) { W_WARNING("error while activating Chilkat"); return; } cSincFTP.ClearSessionLog(); if(sParam.sFTP[nFTP].UsaProxy) { cSincFTP.put_ProxyHostname(sParam.sFTP[nFTP].szServer); cSincFTP.put_ProxyPort (sParam.sFTP[nFTP].unPortaFireWall); cSincFTP.put_ProxyUsername(sParam.sFTP[nFTP].szUserName); cSincFTP.put_ProxyPassword(sParam.sFTP[nFTP].szSenha); //if((nProxyMethod=cSincFTP.DetermineProxyMethod())<=0) return(FALSE); cSincFTP.put_ProxyMethod(nProxyMethod); } cSincFTP.put_Hostname(sParam.sFTP[nFTP].szServer); cSincFTP.put_Username(sParam.sFTP[nFTP].szUserName); cSincFTP.put_Password(sParam.sFTP[nFTP].szSenha); cSincFTP.put_Passive((sParam.sFTP[nFTP].UsaPassiveMode?true:false)); cSincFTP.put_Port(sParam.sFTP[nFTP].unPortaFTP); //Establish an AUTH TLS secure channel after connection on the standard FTP port 21. cSincFTP.put_AuthTls((sParam.sFTP[nFTP].unPortaFTP==990?false:true)); //The Ssl property is for establishing an implicit SSL connection on port 990. cSincFTP.put_Ssl((sParam.sFTP[nFTP].unPortaFTP==990?true:false)); for(;;) { if(cSincFTP.Connect()!=true) { auto razao = cSincFTP.get_ConnectFailReason(); if (razao == 201) { cSincFTP.put_AuthTls(false); cSincFTP.put_AuthSsl(false); cSincFTP.put_Ssl(false); W_MSG("Not possible to use (TLS/SSL)"); continue; } SetCursor(LoadCursor(NULL,IDC_ARROW)); W_WARNING("Not possible to connect to the FTP server"); return; } if(cSincFTP.get_AuthTls()||cSincFTP.get_AuthSsl()||cSincFTP.get_Ssl()) { cSincFTP.ClearControlChannel(); CkString CkHost; cSincFTP.get_Hostname(CkHost); //use the EPSV command instead of PASV for passive mode data transfers cSincFTP.put_UseEpsv(false); //PassiveUseHostAddr property tells the FTP client to discard the IP address part of the PASV response //and replace it with the IP address of the already-established control connection cSincFTP.put_PassiveUseHostAddr(true); } cSincFTP.put_KeepSessionLog(true); break; }; cSincFTP.DeleteRemoteFile(szRemoteFile1); cSincFTP.DeleteRemoteFile(szRemoteFile2); cSincFTP.RemoveRemoteDir(szRemoteDir); cSincFTP.SetTypeBinary(); auto res = cSincFTP.ClearControlChannel(); if(cSincFTP.PutFile(szRemoteFile1,szRemoteFile1)!=true) { //IN here I got the error }
解决方案
该错误核心原因是FTP服务器要求数据连接复用控制连接的TLS会话,当前代码配置未满足此要求,以下是关键修改点:
启用TLS会话恢复:在连接成功后添加配置,让Chilkat在数据连接时复用控制连接的TLS会话:
cSincFTP.put_TlsSessionResumption(true);移除不必要的
ClearControlChannel调用:该操作会重置控制通道的TLS上下文,破坏会话恢复的可能性,需删除连接成功后和PutFile前的两次调用。调整EPSV设置:若服务器支持,建议开启EPSV模式,部分服务器在被动模式下对EPSV的兼容性更好:
cSincFTP.put_UseEpsv(true);
修改后的关键代码片段
for(;;) { if(cSincFTP.Connect()!=true) { auto razao = cSincFTP.get_ConnectFailReason(); if (razao == 201) { cSincFTP.put_AuthTls(false); cSincFTP.put_AuthSsl(false); cSincFTP.put_Ssl(false); W_MSG("Not possible to use (TLS/SSL)"); continue; } SetCursor(LoadCursor(NULL,IDC_ARROW)); W_WARNING("Not possible to connect to the FTP server"); return; } if(cSincFTP.get_AuthTls()||cSincFTP.get_AuthSsl()||cSincFTP.get_Ssl()) { CkString CkHost; cSincFTP.get_Hostname(CkHost); // 启用EPSV(若服务器支持) cSincFTP.put_UseEpsv(true); cSincFTP.put_PassiveUseHostAddr(true); // 启用TLS会话恢复 cSincFTP.put_TlsSessionResumption(true); } cSincFTP.put_KeepSessionLog(true); break; }; // ... 其他代码 cSincFTP.SetTypeBinary(); // 移除此处的ClearControlChannel调用 if(cSincFTP.PutFile(szRemoteFile1,szRemoteFile1)!=true) { // 错误处理 }
内容的提问来源于stack exchange,提问作者israel.sincro
相关产品推荐
相关产品推荐

