Posted on 2007-12-10 22:58
张旭 阅读(2307)
评论(1) 编辑 收藏 引用
从上周三,我才真正了解到我要做的东西(FTPserver)是一个涉及知识极其广泛的复杂程序。而并非之前以为的,单纯的C\S模式文件传输程序。
首先按照老师的提示,配了ftp服务器和web服务器,熟悉了一些ftp命令和配置方法。但是对ftp的通信方式和具体过程还是一无所知。
接下来找来RFC-FTP协议来看,同时参考了telnet协议和http协议。结果还是一头雾水,搞不清楚协议中规定的东西到底应该怎样去实现。
我打算转变思路,动手做试验。模拟了一个服务器端程序,这个程序只能send一条信息和recv一条信息并且打印,然后用linux自带的ftp客户端程序去连接模拟服务器。我想他们之间肯定是有通信来往的,这样做可以观察客户端到底传给服务器怎样形式的信息。经过反复测试。终于搞明白了客户端和服务器之间严格按照RFC-959协议的规定一问一答的通讯方式。
接下来,我就没有着急动手继续写程序,而是去网上搜索了不少关于ftp协议的文档和讨论。了解了双socket-(控制通道,数据通道)。了解了主动传输和被动传输的区别。
看了这些材料以后,我已经大概对整个ftp整个传输过程有一个了解。接下来继续完善了模拟服务器,能够用ftp客户端软件登陆和退出(只做肯定回应)。这样控制通道的通信已经可以正常对话了。剩下的一大问题就是数据通道的通信方式了。
做到这里,我遇到了两个棘手的问题。
Listen()监听函数是如何作用的?按我的理解,listen函数是这道题目中“控制最大同时访问数”的关键。我在编码过程中对这个地方做了试验:当我在while(1)中执行accept时,当接收到客户端connect请求时,fork()建立子进程去处理,父进程继续循环等待accept(),之前listen函数backlog为2。但结果是我仍然可以使用三个以上的ftp客户端进程去同时访问服务器,并保持连接不断开或者阻塞。
两台电脑相互通信,如何取得适合对方访问的自己IP地址?在客户端要求使用被动传输模式的时候,服务器要建立临时的数据传输通道,并把建好的本机地址+新端口,以“msg…. (xxx,xxx,xxx,xxx,xxx,xxx) \r\n”的形式发送给客户端,客户端根据所给的地址和端口号和服务器的数据传输通道建立连接。在C/C++里,可以使用gethostname函数获取本机名称,根据获取的名称,使用gethostbyname函数可以获取本机的IP地址。但是这个IP地址永远是127.0.0.1(至少我的程序中是这样的)。但是这个地址传给对方,对方并不能按照这个地址找到服务器(除非客户端和服务器在同一台电脑上)。如果客户端和服务器在同一局域网中的不同电脑上,那服务器应该传给客户端类似192.168.x.x的地址。如果在internet范围内则需要传送互联网上的IP地址。而真正的ftp服务器和客户端之间的通信,是可以发送适合对方访问自己的IP地址给对方的。而目前所了解到的函数,gethostname和gethostbyname函数并不能完成这项要求。
在网上查了很多资料,关于以上两个问题,有不少存在和我类似情况的提问,不过回答不甚详细。