Ftp协议研究之响应结束标记符

基于tcp传输的ftp client在控制端口发送控制指令给服务器,然后在控制端口等待服务端响应。
问题在于:《TCP/IP协议详解 v1》中介绍服务端的FTP响应指令是以回车换行符结束。只此这样的话,如果响应指令
不只一行(如FEAT指令),且每行都是不定长,客户端根本不知道这些字节流到底多大。这样导致如下的代码
每次做read都会在最后一次超时退出:

  

    for(;;)
    {
        memset(m_cmd_recv,0,sizeof(m_cmd_recv));

        FD_SET(m_control_fd,&rset);

        if ( (nready = select(m_control_fd + 1,&rset,NULL,NULL,&tv))  < 0)
        {
            if(errno == EINTR)//中断
                continue;
            else
            {
                sprintf(m_errorMsg,"ControlConnRead failed:%s",strerror(errno));
                return -1;
            }
        }
        else if (nready == 0)
        {
            sprintf(m_errorMsg,,"%s","ControlConnRead time out");
            return -1;
        }

        if(FD_ISSET(m_control_fd,&rset))
        {
            read(m_control_fd,m_cmd_recv,sizeof(m_cmd_recv));
        
          answer += m_cmd_recv;

            if(string::npos != line.rfind('\n',0))//一定要找到换行符,否则认为失败读取
            {
                break; //获得整行,需返回
            }
            else
            {
                continue;//继续获得完整行
            }
        }

    }


 

   事实是这样吗?
   基于TCP套接口的编程,客户端和服务端双方一般都要进行应用层约定来控制字节流的读取。不外乎两种:
   1.请求和响应都有定长的包头和包体。这样就可以反复调用readn和writen发送指定大小的包。也就是说发送指定大小的数据,接受同样大小的数据。比如SGIP协议

   2.双方以指定结束符来标记字节流的结束。我们可以多次调用read,直到碰到指定的结束标记符为止。

   FTP协议明显不属于第一种约定。第二种呢,《TCP/IP 详解 v1》没明说,Ftp的RFC文档看的不知所云。那么就拿ncftp的client试试。

修改ncftp client的源码:SRead.c中增加如下的打印语句:

          

             ...............
              nread = read(sfd, (char *) buf, nleft);

             if (nread <= 0) {
                        if (nread == 0) {
                                /* printEOF!!!!! */
                                printf("EOF!!!\n\n");
                                 if (retry == ((retry & (kFullBufferRequiredExceptLast)) != 0))
                                        nread = (read_return_t) size - (read_return_t) nleft;
                                goto done;
                        } else if (errno != EINTR) {
                                nread = (read_return_t) size - (read_return_t) nleft;
                                if (nread == 0)
                                        nread = (read_return_t) -1;
                                goto done;
                        } else {
                                errno = 0;
                                nread = 0;
                                /* Try again. */

                                /* Ignore these two lines */
                                LIBSIO_USE_VAR(gSioVersion);
                                LIBSIO_USE_VAR(gCopyright);
                        }
                }

    编程生成可执行程序后,做如下实验:

   实验1:192.168.1.102(centos系统)主机的ncftpclient连接本机的ftp服务器,执行:
                     ./ncftpls -u baijd -p tomcatftp://192.168.1.102
   打印如下:

  EOF!!!

   ftp.sh
   ncftp-3.2.5-src.tar.bz2

   实验2:用92.168.1.102(centos系统)主机的ncftpclient连接windows下的filezalla服务端,执行:
                      ./ncftpls -u baijd -p tomcatftp://192.168.1.101
   EOF!!!

$RECYCLE.BIN
64bak
debian
music
music2
System Volume Information
VGDownloads
Virtual Machines
Warcraft III

   实验证明,ftp服务端真的发送EOF作为控制响应指定的结束符!!!

另记:ncftp要想GDB调试,需要执行:configure --enable-debug.其他用configure->make->make install安装的开源软件大体如此。


   


   

你可能感兴趣的:(编程,centos,tcp,FTP服务器,cmd,null)