Delphi IndyFTP执行PUT后遇Connection Closed Gracefully致大文件损坏
Indy TIdFTP大文件上传损坏问题
问题描述
我在Delphi应用中使用Indy的TIdFTP组件通过FTP向服务器发送压缩文件,应用已部署在数百台客户电脑上。目前有三位客户遇到相同问题:执行Put()命令显示100%完成后,出现“Connection Closed Gracefully”错误,且上传的文件损坏。将服务器上的zip文件下载后用WinRAR打开,会提示“存档意外结束”。
补充信息
- 测试发现仅文件大小超过300MB时触发错误,2MB至140MB文件上传无问题。
- 同一局域网内其他电脑测试结果一致,推测问题与调制解调器或网络基础设施相关,已关闭电脑和调制解调器的防火墙。
原代码与初始错误
IdFTP1.Connect; IdFTP1.TransferType := ftBinary; IdFTP1.Put(strFileName); IdFTP1.Disconnect;
错误发生在第3行IdFTP1.Put(strFileName);,导致无法执行后续的Disconnect()。
后续调整与问题延续
按照Remy的建议修改后问题依旧:
- 启用了NATKeepAlive参数;
- 添加try/except和finally块,代码如下:
IdFTP1.Connect; IdFTP1.TransferType := ftBinary; try//finally try//except IdFTP1.Put(strFileName); except end; finally IdFTP1.Disconnect; end;
修改后程序可正常执行Disconnect(),但上传文件仍损坏,WinRAR仍提示“存档意外结束”。
日志对比分析
为TIdFTP启用TIdLogFile,分别测试14MB小文件和350MB大文件:
小文件上传正常日志
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.
大文件上传损坏日志
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.
日志差异
小文件上传流程完整:发送STOR命令后,收到服务器的150响应,传输完成后收到226 Transfer complete,再发送QUIT并收到221 Goodbye。
大文件上传时,发送STOR和150响应后,没有收到226 Transfer complete就直接发送了QUIT,说明数据连接在文件传输完成前被中断,导致服务器上的文件不完整,最终出现损坏。
内容的提问来源于stack exchange,提问作者Holy Thirteen
相关产品推荐
相关产品推荐

