您的位置:首页 >> 软件资讯 >> 站长专栏 >> 文章正文

SOCKET编程实现简单FTP客户端

2008-3-30 20:28:10 来源:本站原创 作者:李文鹏 点击:1723

    前一段时间看了看socket编程,可也就是看,真正在这方面写过的程序却没有多少,因为以前总是在Linux下用C++写,在家里虽然也装了个Linux,可那天配置了一晚上也没把ADSL给驱动起来,于是这一个假期还一直用着windows,win下的开发工具,用过的也只有vs了,还是找了个vc6.0装上了,网络编程这一块,VC把一些socket给封装了,使用起来简单得多了,不过,还是用最底层的API比较好,因为winsock跟linux环境下的socket大同小异.
  第一次练手应该选一个简单的主题,决定写一个操作FTP的小程序,为此我先查了一些相关的资料,了解了一下有关FTP协议,写一下个人的想法,就不是那么专业了.看了一下win下的ftp.exe,跟cuteftp,flashfxp之类的软件其实原理上都是一样的,用底层的socket来实现,说简单了就两个步骤,用send或write函数向服务器发送命令,服务器接收到命令后向客户发送信息,客户端通过read函数或recv函数读取到服务器发送来的信息,当然过程中还包挺创建套接字,绑定端口,连接服务器之类的操作.大体的步骤就是:socket()->connect()->send()->read().
  客户端与服务器端进行数据交换必须建立两个套接字,一个作为命令通道,一个作为数据通道.前者用于客户端向服务器发送命令,如登录,删除某个文件,更换当前目录等,后者用于接收数据,例如在查看目录文件列表,下载或上传文件等.
  FTP有两种模式,PORT和PASV模式,一种叫主动模式,一种叫被动模式,PORT模式是用户像服务器发送PORT 124,128,249,76,2,25\r\n这种形式的命令,前四个参数是客户端IP地址,后两位是端口,端口的计算方法为port=2*256+25=537,通过这个命令来告诉服务器,客户端的IP,并且在客户端开放了537端口,服务器主动向客户端的537端口发送数据,客户端新建一个套接字作为数据通道,通过监听537端口来获得服务器发送来的数据,这种模式下要注意,客户端计算机上的防火墙是否禁止了537端口.PASV模式是用户向服务器发出"PASV\r\n"命令,然后服务器返回数据:227 Entering Passive Mode (124,128,249,76,4,186),与PORT模式发送的数据形式相似,参数的前四位为服务器的IP地址,后两位为端口号,计算方法也与PORT模式相同,服务器通过这条数据告诉客气端,服务器打开了4*256+186端口,客户端通过连接到该端口来获得服务器发送来的数据.
  在写这个程序的时候遇到了很多白痴问题,弄得自己都很郁闷,不过问题解决了心里也很痛快.刚开始的时候创建一个套接字作为命令通道,可一发送数据就处于阻塞状态,查了很多资料也没能搞定,后来一句话一句话地排查,终于找到症结所在,原来在windows下的send函数的入口参数跟linux是不一样的,虽然大体形式差不多,但数据类型不一致,win的send函数的第二个入口参数是LPSTR数据,而我传入的是char*类型,这种情况下编译器是不会报错的,后来找了很长时间才找到问题所在,send()函数的第三个参数应该使用strlen()来获得命令字符串的长度,而使用sizeof()的时候就会出现阻塞,这样便可以读取到服务器发送来的数据了.另一个问题更让人郁闷,花了我一下午的时间才搞定,最后我都怀疑我自己的智商了,在建立数据通道的时候,connect函数在执行的时候总会返回一个10060错误,用Error Lookup查了一个错误的描述为:由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。服务器是没有问题的,因为是自己的服务器,可以随时查看服务器的运行状态,再一个可能的原因是端口没有开放,如果是防火墙的原因,那FlashFxp用PASV模式也能访问,这个问题排除了,后来又看了下端口,计算的也没有错啊,这一个问题郁闷了一下午,查了N多资料也没能搞定,最后吃饭的时候一想,知道问题出在哪里了,建立数据通道时绑定的端口没有转换成网络数据格式,也就是说忘了调用htons()函数将端口转换了,总是犯这种超没有技术含量的错误,连自己都鄙视自己了.
  最后通过数据通道获得的目录列表是一大堆字符串,下一步的工作就是对这些字符串进行解析,我也就做到这一步了,正在考虑要不要继续玩下去,C++的字符串处理功能没有C#那么牛,字符串解析是一个很让人头痛的问题,有必要的话就先写一个字符串函数库,也方便以后移植到Linux下继续使用.

上一篇: 霍夫曼编码算法C++实现
下一篇:

文章评论[我要评论]

此文章暂无评论