写有一个ftp值守程序,收取FTP目录中的文件。

发现一个很怪的问题:总是接收失败。从服务器发送的字节数看。1440和2880长度是常见的。我令文件的长度恰好是1440或者2880的整数倍,均是失败的多。后不断调试发现。当文件的体积是1440或者2880加上1440的一半稍多时。文件的体积恰好。每次命令发出,都能一次成功接收。比如我现在用的文件体积是2880+1440/2+10=3610,测试良久。成功率99%。而如果长度是1440或者2880的整数倍,结果反过来是:失败率是99%。不知为何。对tcp程序不是很了解。我用的是clientsocket/bcb直接用ftp命令下载文件。在此笔记一下,有时间时再归置归置。

 

之前:

220 Microsoft FTP Service    (win2k3)
 >>>>user ***331 Password required for ***.
 >>>>pass ***230 User *** logged in.
 >>>>cwd db/pd250 CWD command successful.
 >>>>type A
 200 Type set to A.
 >>>>PASV
 227 Entering Passive Mode (*,*,*,*,14,95).
 >>>>NLST
 125 Data connection already open; Transfer starting.
 2010_12_07_14_34_11.txt+++2010_12_07_14_34_11.txt
226 Transfer complete.
 >>>>type I
 200 Type set to I.
 >>>>PASV
 227 Entering Passive Mode (*,*,*,*,16,97).
 >>>>SIZE 2010_12_07_14_34_11.txt213 5760
 >>>>RETR 2010_12_07_14_34_11.txt125 Data connection already open; Transfer starting.


接收到: 2880byte;
接收到: 1440byte;

226 Transfer complete.
 --!!!ftp的SIZE指令报告的字节数还未传完ftp就报告传输结束,这里强制关闭,待下次处理
 >>>>quit
 221  
 >>>>disconnect,Close socket.end.

 

 

之后:

220 Microsoft FTP Service    (win2k3)
 >>>>user ***331 Password required for ***.
 >>>>pass ***230 User *** logged in.
 >>>>cwd db/pd250 CWD command successful.
 >>>>type A
 200 Type set to A.
 >>>>PASV
 227 Entering Passive Mode (*,*,*,*,14,95).
 >>>>NLST
 125 Data connection already open; Transfer starting.
 2010_12_07_14_34_11.txt+++2010_12_07_14_34_11.txt
226 Transfer complete.
 >>>>type I
 200 Type set to I.
 >>>>PASV
 227 Entering Passive Mode (*,*,*,*,16,97).
 >>>>SIZE 2010_12_07_14_34_11.txt213 5760
 >>>>RETR 2010_12_07_14_34_11.txt125 Data connection already open; Transfer starting.
 接收到: 2880byte;
 接收到: 1440byte;
 接收到: 2880byte;
 接收到: 20byte;
 226 Transfer complete.
 --end trans file
 >>>>DELE 2010_12_07_14_17_21.4EC
 250 DELE command successful.
 >>>>quit
 221  
 >>>>disconnect,Close socket.end.


开始处理

 

--------------------------------------------------------------------------------------------

如果要说不是数据长度的缘故,你从3610换成2880马上就是不行。错误可以重现。

出现该错误,有时能重复N次可接收下来,但也有始终循环无法停止的情况。

 

我有另外一个程序,接收文件体积在3100-3900之间,运行数月,无此问题。但如调大调小均也出现此问题。

 

****经常很长时间的运行,发现:

在网络很好的情况下。比如延迟50ms的情况下,没有问题。在延迟200ms的美国主机ftp时频现此问题。

经过反复调试发现。是在csDownLoadTransRead事件中,有如下代码:

       

ilenread = Socket->ReceiveLength();
        DownLoadRev += ilenread;
         //提示可能占据了宝贵的接受时间,造成无法接收
         //测试:把下面这句取消注释,错误重现,一个文件下载几次都下载不完整。
         //reMailInfo->Text = reMailInfo->Text + "接收到: " + IntToStr(ilenread)+"byte;\r\n";
         //reMailInfo->Lines->Add("接收到: " + IntToStr(ilenread)+"byte;");    //这句也不行,看来只要引起界面刷新的,效率都低下。
         
         Socket->ReceiveBuf(&szbuff,ilenread);   //读后长度变为零,特别注意
         of.write(szbuff,ilenread);

        就是reMailInfo->Text 插入时影响到了效率。注释掉,反复测试美国主机(ping延迟200ms左右)恢复了正常。看来问题就出在此。