关于FTP程序接收文件的问题

来源:互联网 发布:v盾网络验证 编辑:程序博客网 时间:2024/06/06 05:53

写有一个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/pd

250 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.txt

213 5760
>>>>RETR 2010_12_07_14_34_11.txt

125 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/pd

250 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.txt

213 5760
>>>>RETR 2010_12_07_14_34_11.txt

125 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左右)恢复了正常。看来问题就出在此。