我正在使用Indy的TIdFTP
通过FTP从 Delphi 应用程序将压缩文件发送到服务器。该应用程序在数百名客户的计算机上使用。三个客户面临同样的问题。在执行Put()
命令后,在文件上传100%结束时,出现“连接已优雅关闭”错误,上传的文件已损坏。
当从服务器下载zip文件并尝试打开它时,Winrar说:
意外的存档结束
其他信息:
- 我开发了另一个测试应用程序来调试这个问题。这个错误发生在大小超过300MB的文件上。我测试了从2MB到140MB的上传文件,没有问题。
- 我在同一LAN网络中的另一台计算机上进行了测试,结果是相同的。因此,似乎问题与调制解调器或互联网基础设施有关。计算机或调制解调器上没有活动的防火墙,我禁用了每台计算机上调制解调器和Windows上的防火墙。
源代码如下:
IdFTP1.Connect;
IdFTP1.TransferType := ftBinary;
IdFTP1.Put(strFileName);
IdFTP1.Disconnect;
错误发生在第3条语句上,它阻止了与服务器断开连接。
补充说明:
正如雷米所说,我改变了一些东西,但结果是一样的。
- 我通过如图所示的参数激活了
NATKeepAlive
:
我添加了finally
和except
块,所以代码如下所示:
IdFTP1.Connect;
IdFTP1.TransferType := ftBinary;
try//finally
try//except
IdFTP1.Put(strFileName);
except
end;
finally
IdFTP1.Disconnect;
end;
修改后,程序执行Disconnect()
命令,但上传的文件已经损坏。当我想打开上传的zip文件时,Winrar仍然说'unexpected end of archive',如下图所示:
我在TIdFTP
连接上开启了TIdLogFile
,对一个**小文件(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.
大文件的日志文件(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.
1条答案
按热度按时间5anewei61#
FTP协议使用多个TCP连接-一个用于主命令通道,一个用于数据通道上的每个传输。
当数据传输正在进行时,命令通道处于空闲状态。对于不了解FTP如何工作的网络系统来说,如果在长时间的数据传输期间命令通道空闲时间过长,则断开命令通道是很常见的。这可以解释为什么您只在大文件上看到问题。当
TIdFTP.Put()
试图读取服务器的最终响应时,它可能会表现为“Connection Closed Gracefully”错误(或许多其他套接字错误之一)。TIdFTP
有一个NATKeepAlive
属性,通过在数据传输忙碌时在命令通道的TCP连接上启用TCP级别的keepalive来帮助防止此问题。默认情况下,NATKeepAlive.UseKeepAlive
属性为False
。请尝试将其设置为True
,并为NATKeepAlive.IdleTimeMS
和NATKeepAlive.IntervalMS
属性设置合适的超时。这样,在数据传输期间,如果命令信道曾经空闲了IdleTimeMS
毫秒,则TCP保活分组将每IntervalMS
毫秒在命令TCP连接上被发送,直到数据传输完成。