免费注册 查看新帖 |

Chinaunix

广告
  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 8333 | 回复: 12
打印 上一主题 下一主题

有趣的FTP客户端,编写FTP服务器有感 [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-11-02 11:54 |只看该作者 |倒序浏览
自己写了一个多线程FTP服务器
测试中遇到无数烂客户端,从而不断改进
同时逐渐明白为啥win32的FTP客户端要收费了

1、win2k的IE6
这个IE6很有趣,它同时发起两个连接到FTP服务器
一个用于LIST/MKD/DELE,另一个用于RETR/STOR
问题是这两个连接没有正确共享帐号,如果第一次登录出错,改正帐号后
只有一个连接被更正,然后浏览器就死循环,重开IE才能恢复正常
重开IE之前,俺的FTP登录日志会无限增长,正确和错误交替出现

2、winXP的IE6
这个IE6除了双连接以外,有另外一项功能,在上传目录时,每个目录要创建两次
vsFTP会耐心的返回550错误,我经过考虑,决定当目录已经创建时,返回成功而不是550
这下XP的IE6不用我去点鼠标了,但是上传完毕,IE窗口显示文件和目录都是双份
刷新页面后正常,显然,这个IE6在上传之后没有LIST,而是根据自己的操作记录显示

3、win2003上的IE7
这个一切正常

我用LINUX的gFTP从来没提要钱的事情,没有这样那样的有趣行为
但是win32的FTP客户端,稍微好用一点的都要钱

现在我理解vsFTP为啥在LIST之后连续返回150和226响应了,因为IE6没有接到226就不接收数据通道内容
可是传输文件千万不能把150和226一起发,那样的话FlashFXP会直接中断数据连接
所以传目录时,150和226一起发,传文件时,数据通道关闭再发226

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2007-11-02 12:00 |只看该作者
呵呵,我现在就在写一个你所说的“烂客户端”,看来我们俩是死对头。
我这个客户端要求服务器支持多线程上传同一个文件,你的服务器支持吗?
我现在测试过 vsftpd pureftpd proftpd,都不支持,只有 wu-ftpd 支持,但是有个小小的 BUG,不过可以绕过去。

论坛徽章:
0
3 [报告]
发表于 2007-11-02 13:11 |只看该作者
这个,多线程上传同一个文件,
很容易写个程序把服务器弄挂吧?

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2007-11-02 13:50 |只看该作者
原帖由 flw 于 2007-11-2 12:00 发表
呵呵,我现在就在写一个你所说的“烂客户端”,看来我们俩是死对头。
我这个客户端要求服务器支持多线程上传同一个文件,你的服务器支持吗?
我现在测试过 vsftpd pureftpd proftpd,都不支持,只有 wu-ftpd  ...


多线程下载可以,上传不行,文件会乱掉

我的接收文件算法是这样实现的
在数据连接正确建立之后
首先生成带绝对路径的真正文件名
在一个所有用户都不可见的临时目录里,用线程id为临时文件名
接收数据
当数据接受完毕之后
用rename()将这个临时文件改名为真正的文件名

如果上传之前客户用了REST
那么会将目的文件rename()为临时文件
fseek(fp, REST值,SEEK_SET)
传输完成后再rename()回去

如果要支持多线程上传
临时文件就要带上REST信息和实际传输长度
并且需要编写一个函数把这若干个碎片文件合并
由于标准FTP协议不能预先知道文件大小,这个合并程序要考虑很多异常才行

我打算将来实现这个多线程上传支持
不过最近在赶时间

至于传输过程正在写入的文件对用户不可见,是应用的要求,这个不能修改

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
5 [报告]
发表于 2007-11-02 14:01 |只看该作者
原帖由 safedead 于 2007-11-2 13:50 发表


多线程下载可以,上传不行,文件会乱掉

我的接收文件算法是这样实现的
在数据连接正确建立之后
首先生成带绝对路径的真正文件名
在一个所有用户都不可见的临时目录里,用线程id为临时文件名
接收数据 ...

的确是这样,多线程上传是比较难做,需要考虑的问题比较多。
况且也不太常用。
FTP 协议规范是支持的,服务器实现的时候通常都不能很好的支持 REST+STOR

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
6 [报告]
发表于 2007-11-02 14:44 |只看该作者

继续

多线程上传对我的程序来讲
最大的问题是异步合并
比如文件被平均拆开成5块传输
没准第5块会第一个传完,因为最后一块往往是最小的一块!
必须等待所有的段落传输完毕才能正确合并
这个合并过程不应该阻塞任何一个相关的FTP会话线程

我应该去参考一下BT的做法,那个在大文件合并和异步问题的处理解决的非常好

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
7 [报告]
发表于 2007-11-02 14:50 |只看该作者
原帖由 safedead 于 2007-11-2 14:44 发表
多线程上传对我的程序来讲
最大的问题是异步合并
比如文件被平均拆开成5块传输
没准第5块会第一个传完,因为最后一块往往是最小的一块!
必须等待所有的段落传输完毕才能正确合并
这个合并过程不应该阻塞任 ...

我觉得 wu-ftpd 的做法很直观,很正确。
它是直接打开目标文件 seek 后写的。
只不过你刚才说了,你的应用要求必须要有临时文件。

论坛徽章:
0
8 [报告]
发表于 2007-11-02 15:00 |只看该作者
原帖由 flw 于 2007-11-2 14:50 发表

我觉得 wu-ftpd 的做法很直观,很正确。
它是直接打开目标文件 seek 后写的。
只不过你刚才说了,你的应用要求必须要有临时文件。


請問他有對seek次數做優化嗎?

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
9 [报告]
发表于 2007-11-02 15:08 |只看该作者
原帖由 飞灰橙 于 2007-11-2 15:00 发表

請問他有對seek次數做優化嗎?

应该没有吧。
它好像是一个连接就是一个进程/线程。
然后多个连接并发写同一个文件,用 O_RDWR 打开,seek 到 REST 指定的偏移量,如果长度不够就会扩展空洞。

论坛徽章:
0
10 [报告]
发表于 2007-11-02 15:22 |只看该作者
原帖由 safedead 于 2007-11-2 14:44 发表
多线程上传对我的程序来讲
最大的问题是异步合并
比如文件被平均拆开成5块传输
没准第5块会第一个传完,因为最后一块往往是最小的一块!
必须等待所有的段落传输完毕才能正确合并
这个合并过程不应该阻塞任 ...

为何不换个方法,预先知道每一块在文件中的位置,直接写文件,互不干扰
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP