Linux下的ftp客户端说明文档

Linux下的ftp客户端说明文档

l         软件功能:

    本程序基于linux下的socket函数,利用ftp 协议,实现linux下,连接上ftp server,对文件,整个文件夹的上传和下载,以及浏览ftp server 的内容。

l         使用说明:

    //  usage :

    //  connect :           ftp.out 10.10.10.10 21

    //  download file:          get filename

    //  upload file :       put filename

    //  download directory: d filename

    //  upload directory :  u filename

    // list :              list

    // list :              dir

    //  quit :              quit



l         函数主体说明:

    enum COMMAND getcmd(struct ftp_client *);// get user input

    int getline(char *);                        // get a line of input

    int getport(char *);                        // get port of data socket

    int pasv( struct ftp_client *);         // enter pasive mode in ftp

    int list( struct ftp_client *);         // list file in server

    int get( struct ftp_client *);          // download file

    int cwd( struct ftp_client *);          // change directory of ftp server

    int get_d(struct ftp_client *);         // download dirctory

    int print_list( struct ftp_client *);   // print file name in a list file

    int get_file ( struct ftp_client *);        // downlaod file

    int analyse ( struct ftp_client *);     // got name of the file and directory



   

l         ftp协议说明:

文件传输协议(File Transfer Protocol, FTP)

1. 介绍

        FTP的目标是提高文件的共享性,提供非直接使用远程计算机,使存储介质对用户         透明和可靠高效地传送数据。



2. 数据传输功能

        数据连接只传输数据,控制连接传送命令和响应。



3. 传输模式



        有三种传输模式:一种将数据格式化并考虑重新开始过程;一种压缩数据;一种      是不经过处理(少量处理)传送。



    4. 流模式

        数据以字节流的形式传送。使用的表示类型没有限制,允许记录结构。

   

    5. 访问控制命令

        下列命令指定访问控制标记(命令码在括号内):

        用户名(USER)

        参数是标记用户的Telnet串。

        口令(PASS)

        参数是标记用户口令的Telnet串。此命令紧跟USER命令,在某些站点它是完成      访问    控制不可缺少的一步。

        改变工作目录(CWD)

        此命令使用户可以在不同的目录或数据集下工作而不用改变它的登录或帐户信            息。传  输参数也不变。参数一般是目录名或与系统相关的文件集合。

   

    6.传输参数命令

        所有数据传输参数有默认值。服务器必须记录下默认值,在FTP服务请求后,可      以以    任何顺序发送。下面命令传送参数:

        数据端口(PORT)

        参数是要使用的数据连接端口,通常情况下对此不需要命令响应。如果使用此命      令时,要发送32位的IP地址和16位的TCP端口号。上面的信息以8位为一组,       逗号间隔十进制传输,如下例:

        PORT h1,h2,h3,h4,p1,p2

        其中h1是IP地址的最高8位。

   

    7.被动(PASV)

        此命令要求服务器DTP在指定的数据端口侦听,进入被动接收请求的状态,参数      是主    机和端口地址。

   

    8.表示类型(TYPE)

        参数指定表示类型。

   

    9. FTP服务命令

        获得文件(RETR)

            此命令使服务器DTP传送指定路径内的文件复本到服务器或用户DTP。这边服         务器上文件的状态和内容不受影响。

        保存(STOR)

            此命令使服务器DTP接收数据连接上传送过来的数据,并将数据保存在服务          器的文件中。如果文件已存在,原文件将被覆盖。如果文件不存在,则新建            文件。

        创建目录(MKD)

            此命令在指定路径下创建新目录。

        打印工作目录(PWD)

            在响应是返回当前工作目录。

        系统(SYST)

            用于确定服务器上运行的操作系统。

    10.FTP应答

        1yz 确定预备应答

            请求的操作正在被初始化;在进入下一个命令前等待另外的应答。这类响应          用于说明命令被接受,在实现中如何同步监视有困难,用户进程现在可以关          注数据连接了。服务器FTP进程对第个命令几乎都返回1yz响应。

        2yz 确定完成应答

            要求的操作已经完成,可以执行新命令。

        3yz 确定中间应答

            命令已接受,但要求的操作被停止,停止接收更新的信息。

        4yz 暂时拒绝完成应答

            未接受命令,要求的操作未执行,但错误是临时的,过一会儿可以再次发送          消息。用户应该返回命令序列的开始。这个暂时可是不好确定,此命令的意            思就是让用户进程再次尝试使用此命令。

        5yz 永远拒绝完成应答

            它与暂时拒绝完成应答的区别就在于错误条件是一时半会不会消失。

        x0z 格式错误;

            x1z 此类应答是为了请求信息的;

            x2z 此类应答是关于控制和数据连接的;

            x3z 关于认证和帐户登录过程;

            x4z 未使用;

            x5z 此类应答是关于文件系统的;

        

        下面根据数字顺序列出各个应答码及其意义:

        125

        数据连接已打开,准备传送

        150

        文件状态良好,打开数据连接

        200

        命令成功

        202

        命令未实现

        215

        名字系统类型

        220

        对新用户服务准备好

        221

        服务关闭控制连接,可以退出登录

        225

        数据连接打开,无传输正在进行

        226

        关闭数据连接,请求的文件操作成功

        227

        进入被动模式

        230

        用户登录

        250

        请求的文件操作完成

        331

        用户名正确,需要口令

        332

        登录时需要帐户信息

        421

        不能提供服务,关闭控制连接

        425

        不能打开数据连接

        426

        关闭连接,中止传输

        450

        请求的文件操作未执行

        451

        中止请求的操作:有本地错误

        500

        格式错误,命令不可识别

        501

        参数语法错误

        502

        命令未实现

        503

        命令顺序错误

        530

        未登录

        550

        未执行请求的操作

        551

        请求操作中止:页类型未知

        552

        请求的文件操作中止,存储分配溢出

        553

        未执行请求的操作:文件名不合法



l         技术难点分析:

1, list命令之后,对list_ftp文件名的处理,以下是实现的算法:

    这部分的内容由analyse函数实现:

    int analyse ( struct ftp_client *p)     

    {

   



   

    打开文件

        while(文件没有结束)

   {

        获取一个字符      

        标记是否是文件

        跳过8个字符串

        把剩下的全读进来作为名字保存        

        如果是文件

            压到栈中

            创建这个文件            

    }  

    }



2, 下载目录时的堆栈操作。



int get_local_file ( struct ftp_client *p)              // upload all the file in this level and push directory to stack

{   

        先把p->path备份

        strcpy(recover,p->path);        

        while(p->path[n++]);    //  n is current path length

        算出路径的长度,下面用malloc时用

        analyse_local(p);   // name is store in p->buf

        分析当前层的文件结构,下载文件,压栈文件夹

        while(p->tell >0)   当栈里还有文件夹时

        {

            如果是文件

            if ( p->file[p->tell-1] == 0 )      //    == file   why don't tell the file name ? file name

            {

                下载文件

            }

            如果是文件夹

            else if (p->file[p->tell-1] == 1 )      //   == directory

            {

                把文件夹一个个压到栈里

            }

            p->tell--;      // one file in current directory is processed

        }

        return 1;

}







l         进一步的改进

1. 应该完善出错处理机制,网络常常会出错,那么就不能假设一切传输都是按照预期的那样,目前这个程序有报错的处理,但是出错后,有一些情况是报错后程序中止,而不是回到主循环里,那么又需要重新登陆,麻烦。协议端口可以用非阻塞式传输,用一个常量try_time控制检测次数。这样可以使这个程序用起来更方便。

2. 可以考虑实现当前本地目录可以改变的功能。

3. 可以考虑实现ftp里的更多功能,比如删除server上的文件等。

4. 压栈操作里用了常量buffer,有点浪费内存,可以改成malloc来动态分配名字的长度和buffer的长度。虽然这样写容易出错。

5. 可以考虑移植到windows下,只要把socket部分换成winsock就基本上可以了,还有一个wsastartup函数

6. 可以考虑移植到图形界面,用qt或gtk编程。



l         心得:

1. 出错的重点和排错的重点还是边界处理,用gdb或者kdevelop可以debug,但是没有vc方便,可以把主要算法拷贝到vc里去排除错误,有那个自动添加变量功能,还有快捷键,可以提高不少效率。

2. 数据结构还是算法的关键,堆栈处理又是数据结构中很重要的部分,要尽量熟练应用。还有二叉树的遍历等都该复习复习了。

3. Linux下编程windows下编程有所不同,没有mfc这种大的构架可以利用,但是也有很多小命令,可以尽量利用shell里的函数和功能,例如ls之类的,还有rm,mkdir等等,用system调用或exec函数都可以。

4. socket网络编程的调试比较麻烦,也没什么好办法,我的经验是用大量的printf语句把重要的变量打出来,然后看看屏幕就可以跟踪分析其中的问题。用kdevelop之类的调试的话也不错,就是不能自动添加变量,每次调都得重新输一遍。

5. 编程还是要考虑模块化,或者对象化,以利于进一步的移植。
好的
可以上传代码看看好不?