免费注册 查看新帖 |

Chinaunix

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

ftp 的socket问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-10-12 16:56 |只看该作者 |倒序浏览
我在linux下用socket实现ftp客户端,对于list这个命令,我代码实现如下
int uc_FtpClient::ListDir()
{
    bool bRet = ftpListen();//实现数据链路的监听
   strCommand = "LIST\r\n";
     bRet = SendCommand( strCommand);
     bRet = RecvCommandEcho(strMsg); //问题出现在这,
   //strMsg是:“150 here comes the directory listing.\r\n226 Directory send ok\r\n"
     std::cout << strMsg << std::endl; //但前两三次,
   //这里显示:150 here comes the directory listing.\r\n.  
     //226 Directory send ok\r\n 没有显示,两三次后,这句也出现
   bRet = ftpCreateDataChannel();//创建数据传输通道
   long recv_size = RecvData( cBuf, MAX_FILE_LEN );//接收传回来的数据
     std::cout << cBuf << std::endl; //显示接收到的目录信息
   ftpCloseDataListen(); //数据传送通道关闭
   RecvCommandEcho( strMsg ); //再次接收一次命令返回码
   //前两三次,因为,上面的RecvCommandEcho( strMsg );只接收到一句,这句运行良好
}

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2006-10-12 20:36 |只看该作者
1.不要用C++搞FTP

2.以vsftp为例:
第一次LIST, 流程如下:
C->S: PASV
S->C: 227 .Enter passive mode (a,b,c,d,e,f)
C->S: LIST
S->C: 150 here
S->C: (data)
S->C: 226

如果对同一目录第二次LIST,则:
C->S: PASV
S->C: 227 .Enter passive mode (a,b,c,d,e,f)
C->S: LIST
S->C: 150 here
S->C: 226
S->C: (data)

而windows的IIS不这样,总是第一种
150和226同时发送是FTP流水线响应扩展,
客户端程序应该考虑到

论坛徽章:
0
3 [报告]
发表于 2006-10-12 21:36 |只看该作者
应该还有 extended passive mode

另外,看看各种系统上自带的 ftp 程序的代码,尽量不要用别人提供的所谓函数库。能自己实现,达到目的的,就避免用别人的库。

BTW,楼主的注释写成这样,没几个人能看明白。

论坛徽章:
39
2017金鸡报晓
日期:2017-02-08 10:39:4219周年集字徽章-周
日期:2023-04-15 12:02:2715-16赛季CBA联赛之深圳
日期:2023-02-16 14:39:0220周年集字徽章-年
日期:2022-08-31 14:25:28黑曼巴
日期:2022-08-17 18:57:0919周年集字徽章-年
日期:2022-04-25 13:02:5920周年集字徽章-20	
日期:2022-03-29 11:10:4620周年集字徽章-年
日期:2022-03-14 22:35:1820周年集字徽章-周	
日期:2022-03-09 12:51:3220周年集字徽章-年
日期:2022-02-10 13:13:4420周年集字徽章-周	
日期:2022-02-03 12:09:4420周年集字徽章-20	
日期:2022-01-25 20:14:27
4 [报告]
发表于 2006-10-12 22:44 |只看该作者
原帖由 safedead 于 2006-10-12 20:36 发表
1.不要用C++搞FTP

2.以vsftp为例:
第一次LIST, 流程如下:
C->S: PASV
S->C: 227 .Enter passive mode (a,b,c,d,e,f)
C->S: LIST
S->C: 150 here
S->C: (data)
S->C: 226

如果对 ...


C++不能做FTP的东西?不会吧。

论坛徽章:
0
5 [报告]
发表于 2006-10-13 08:43 |只看该作者
原帖由 safedead 于 2006-10-12 20:36 发表
1.不要用C++搞FTP

2.以vsftp为例:
第一次LIST, 流程如下:
C->S: PASV
S->C: 227 .Enter passive mode (a,b,c,d,e,f)
C->S: LIST
S->C: 150 here
S->C: (data)
S->C: 226

如果对 ...

我如何分析这种流程差别。我使用判断是否有“226...."但也不行,每次都判断到,而导致有返回码没读到,如果不判断,几次后,最后一个RecvCommandEcho()却在死等而读不到数据。如何办?

论坛徽章:
0
6 [报告]
发表于 2006-10-13 09:15 |只看该作者
我在gdb下,每次都得到“150 here comes the directory listing.\r\n226 Directory send ok\r\n”,都能打印这句,但是在普通方式下,却有时候只打印前一句,有时候打印两句。不知有谁知道?

论坛徽章:
0
7 [报告]
发表于 2006-10-13 10:13 |只看该作者
也就是说:对于socket的receive数据,每次都能读到“150 here comes the directory listing.\r\n226 Directory send ok\r\n”,但是用cout<< msg <<endl打印的时候有时却只能打印“150 here comes the directory listing.\r\n”,有时能全部打印,但每次查找“226”这个字符串(msg.find("226") >0 )的时候都能是真。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
8 [报告]
发表于 2006-10-15 23:48 |只看该作者
其实不光是150和226响应可能会在一次recv()中收到
一般公网上的FTP大站在USER/PASS成功之后会发送
带有很多行类似2xx-abcd\r\n的响应,需要收齐之后才能发命令
否则是乱的,需要按照类似HTTP的方式接受多行响应(这不是RFC959的内容)

如果是IPv6的FTP
则需要用EPSV取代PASV
227响应的格式变成:
227 (||||port)\r\n

不过,服务器发送150和226确实不是一次发出的,但TCP的NAGLE算法捣鬼
会把相隔很近的两次send()合并成一个TCP报文,结果你有时recv()一次就收到了,
但有时226却是在断开数据连接之后收到

FTP协议看似简单,但编写FTP代理服务器就特别麻烦
比编客户端还要麻烦
比如某些情况下recv()收到的只是半行响应(缺\r\n),这些都要判断,
否则客户端连接FTP代理会卡住(IE和FireFOX都等待完整的FTP响应行)
而FlashGET之类则会容忍轻微的格式错误(“错误”指没有严格符合RFC959)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP