我正在使用 Indy'sTIdFTP通过 FTP 从 Delphi 应用程序将压缩文件发送到服务器。该应用程序在数百台客户的计算机上使用。三个客户面临着同样的问题。执行命令后Put(),在 100% 传输的文件上传结束时,会出现“连接正常关闭”错误,并且上传的文件已损坏。
当从服务器下载 zip 文件并尝试打开它时,Winrar 说:
存档意外结束
附加信息:
源代码如下:
IdFTP1.Connect;
IdFTP1.TransferType := ftBinary;
IdFTP1.Put(strFileName);
IdFTP1.Disconnect;
Run Code Online (Sandbox Code Playgroud)
该错误发生在第三条语句上,并且它阻止与服务器断开连接。
附加说明:
正如雷米所说,我改变了一些东西,但结果是一样的。
NATKeepAlive通过如图所示的参数激活:我添加了finallyandexcept块,所以代码如下所示:
IdFTP1.Connect;
IdFTP1.TransferType := ftBinary;
try//finally
try//except
IdFTP1.Put(strFileName);
except
end;
finally
IdFTP1.Disconnect;
end;
Run Code Online (Sandbox Code Playgroud)
更改后,程序执行Disconnect()命令,但上传的文件已损坏。当我想打开上传的 zip 文件时,Winrar 仍然显示“存档意外结束”,如下图所示:
我启用了TIdLogFile我的TIdFTP连接。对一个小文件(14MB)和一个大文件(350MB)测试程序两次。上传的小文件工作正常,但上传的大文件已损坏。调试日志结果如下图:
小文件的日志文件 (14MB):
Stat Connected.
Recv 03/04/2023 10:29:31: 220 ProFTPD Server (ProFTPD) [***.***.***.***]<EOL>
Sent 03/04/2023 10:29:31: HOST ***.***.***.***<EOL>
Recv 03/04/2023 10:29:31: 220 HOST command successful<EOL>
Sent 03/04/2023 10:29:31: USER *******<EOL>
Recv 03/04/2023 10:29:31: 331 Password required for ******<EOL>
Sent 03/04/2023 10:29:31: PASS *******<EOL>
Recv 03/04/2023 10:29:31: 230 User ****** logged in<EOL>
Sent 03/04/2023 10:29:31: FEAT<EOL>
Recv 03/04/2023 10:29:31: 211-Features:<EOL>
Recv 03/04/2023 10:29:31: AUTH TLS<EOL> CCC<EOL> CLNT<EOL>
Recv 03/04/2023 10:29:31: EPRT<EOL> EPSV<EOL> HOST<EOL> LANG en-US.UTF-8*<EOL> MDTM<EOL> MFF modify;UNIX.group;UNIX.mode;<EOL> MFMT<EOL> MLST modify*;perm*;size*;type*;unique*;UNIX.group*;UNIX.groupname*;UNIX.mode*;UNIX.owner*;UNIX.ownername*;<EOL> PBSZ<EOL> PROT<EOL> RANG STREAM<EOL> REST STREAM<EOL> SIZE<EOL> SSCN<EOL> TVFS<EOL> UTF8<EOL>211 End<EOL>
Sent 03/04/2023 10:29:31: CLNT Indy 10.6.2.0<EOL>
Recv 03/04/2023 10:29:31: 200 OK<EOL>
Sent 03/04/2023 10:29:31: OPTS UTF8 ON<EOL>
Recv 03/04/2023 10:29:31: 200 UTF8 set to on<EOL>
Sent 03/04/2023 10:29:31: TYPE I<EOL>
Recv 03/04/2023 10:29:31: 200 Type set to I<EOL>
Sent 03/04/2023 10:29:31: SYST<EOL>
Recv 03/04/2023 10:29:31: 215 UNIX Type: L8<EOL>
Sent 03/04/2023 10:29:31: TYPE I<EOL>
Recv 03/04/2023 10:29:31: 200 Type set to I<EOL>
Sent 03/04/2023 10:29:31: PASV<EOL>
Recv 03/04/2023 10:29:31: 227 Entering Passive Mode (***.***.***.***,213,225).<EOL>
Sent 03/04/2023 10:29:32: MLSD _test<EOL>
Recv 03/04/2023 10:29:32: 150 Opening BINARY mode data connection for MLSD<EOL>
Recv 03/04/2023 10:29:32: 226 Transfer complete<EOL>
Sent 03/04/2023 10:29:32: CWD _test<EOL>
Recv 03/04/2023 10:29:32: 250 CWD command successful<EOL>
Sent 03/04/2023 10:29:32: PASV<EOL>
Recv 03/04/2023 10:29:32: 227 Entering Passive Mode (***.***.***.***,232,86).<EOL>
Sent 03/04/2023 10:29:32: STOR MySmallFile.zip<EOL>
Recv 03/04/2023 10:29:32: 150 Opening BINARY mode data connection for MySmallFile.zip<EOL>
Recv 03/04/2023 10:29:52: 226 Transfer complete<EOL>
Sent 03/04/2023 10:29:52: QUIT<EOL>
Recv 03/04/2023 10:29:52: 221 Goodbye.<EOL>
Stat Disconnected.
Run Code Online (Sandbox Code Playgroud)
大文件的日志文件 (350MB):
Stat Connected.
Recv 03/04/2023 10:30:51: 220 ProFTPD Server (ProFTPD) [***.***.***.***]<EOL>
Sent 03/04/2023 10:30:51: HOST ***.***.***.***<EOL>
Recv 03/04/2023 10:30:51: 220 HOST command successful<EOL>
Sent 03/04/2023 10:30:51: USER *********<EOL>
Recv 03/04/2023 10:30:51: 331 Password required for *****<EOL>
Sent 03/04/2023 10:30:51: PASS *********<EOL>
Recv 03/04/2023 10:30:51: 230 User ******** logged in<EOL>
Sent 03/04/2023 10:30:51: FEAT<EOL>
Recv 03/04/2023 10:30:51: 211-Features:<EOL> AUTH TLS<EOL> CCC<EOL> CLNT<EOL> EPRT<EOL> EPSV<EOL> HOST<EOL> LANG en-US.UTF-8*<EOL>
Recv 03/04/2023 10:30:51: MDTM<EOL> MFF modify;UNIX.group;UNIX.mode;<EOL> MFMT<EOL> MLST modify*;perm*;size*;type*;unique*;UNIX.group*;UNIX.groupname*;UNIX.mode*;UNIX.owner*;UNIX.ownername*;<EOL> PBSZ<EOL> PROT<EOL> RANG STREAM<EOL> REST STREAM<EOL> SIZE<EOL> SSCN<EOL> TVFS<EOL> UTF8<EOL>211 End<EOL>
Sent 03/04/2023 10:30:51: CLNT Indy 10.6.2.0<EOL>
Recv 03/04/2023 10:30:51: 200 OK<EOL>
Sent 03/04/2023 10:30:51: OPTS UTF8 ON<EOL>
Recv 03/04/2023 10:30:51: 200 UTF8 set to on<EOL>
Sent 03/04/2023 10:30:51: TYPE I<EOL>
Recv 03/04/2023 10:30:51: 200 Type set to I<EOL>
Sent 03/04/2023 10:30:51: SYST<EOL>
Recv 03/04/2023 10:30:51: 215 UNIX Type: L8<EOL>
Sent 03/04/2023 10:30:51: TYPE I<EOL>
Recv 03/04/2023 10:30:51: 200 Type set to I<EOL>
Sent 03/04/2023 10:30:51: PASV<EOL>
Recv 03/04/2023 10:30:51: 227 Entering Passive Mode (***.***.***.***,213,173).<EOL>
Sent 03/04/2023 10:30:51: MLSD _test<EOL>
Recv 03/04/2023 10:30:51: 150 Opening BINARY mode data connection for MLSD<EOL>
Recv 03/04/2023 10:30:51: 226 Transfer complete<EOL>
Sent 03/04/2023 10:30:51: CWD _test<EOL>
Recv 03/04/2023 10:30:51: 250 CWD command successful<EOL>
Sent 03/04/2023 10:30:51: PASV<EOL>
Recv 03/04/2023 10:30:51: 227 Entering Passive Mode (***.***.***.***,222,56).<EOL>
Sent 03/04/2023 10:30:51: STOR MyBigFile.zip<EOL>
Recv 03/04/2023 10:30:51: 150 Opening BINARY mode data connection for MyBigFile.zip<EOL>
Sent 03/04/2023 10:40:24: QUIT<EOL>
Stat Disconnected.
Run Code Online (Sandbox Code Playgroud)
Rem*_*eau 10
FTP 协议使用多个 TCP 连接 - 一个用于主命令通道,一个用于数据通道上的每次传输。
当数据传输正在进行时,命令通道处于空闲状态。对于不知道 FTP 工作原理的网络系统来说,如果在长时间的数据传输过程中空闲时间过长,则断开命令通道的情况并不罕见。这可以解释为什么您只看到问题发生在大文件上,并且当尝试读取服务器的最终响应时,它可能表现为“连接正常关闭”错误(或许多其他套接字错误之一) 。TIdFTP.Put()
TIdFTP有一个NATKeepAlive属性可以帮助防止此问题,方法是在数据传输繁忙时在命令通道的 TCP 连接上启用 TCP 级保活。该NATKeepAlive.UseKeepAlive属性是False默认的。尝试将其设置为相反,并为和属性True设置合适的超时。这样,在数据传输期间,如果命令通道空闲了几毫秒,则每毫秒都会在命令 TCP 连接上传输 TCP keepalive 数据包,直到数据传输完成。NATKeepAlive.IdleTimeMSNATKeepAlive.IntervalMSIdleTimeMSIntervalMS
| 归档时间: |
|
| 查看次数: |
1027 次 |
| 最近记录: |