Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > C/C++ > FileZilla FTP服务器源代码分析13
【标  题】:FileZilla FTP服务器源代码分析13
【关键字】:FileZilla,FTP
【来  源】:http://blog.csdn.net/wanghaoguang/archive/2006/09/07/1187315.aspx

FileZilla FTP服务器源代码分析13

Your Ad Here

前面已经分析过了FTP客户登录服务器的过程,现在来看一下常见的ls命令的处理过程。

用户在FTP客户端输入ls命令后,ftp.exe首先发出port请求给服务器,在CControlSocket的ParseCommand()中被处理。

PORT命令的参数是形如:127.0.0.1.4.9,前4个表示客户端的IP地址,后两个根据规则4 * 256 + 9 = 1033,表示FTP客户端临时建立的用来与服务器建立数据连接的端口,例子所示为1033端口。

PORT命令的处理过程的代码中前面都是用来获取IP和临时端口的:

case COMMAND_PORT:
 ...
 port += 256 * _ttoi(args.Right(args.GetLength() - (i + 1))); // add ms byte to server socket
 ip = args.Left(i);
 ...

下面:
 m_transferstatus.ip = ip;
 m_transferstatus.port = port;
 m_transferstatus.pasv = 0;
 Send(_T("200 Port command successful"));
 break;
只是将FTP客户端提供的临时端口记录到m_transferstatus中,然后发出200 Port command successful,等待FTP客户端的下一个命令。由于用户输入的是ls命令,ftp.exe在PORT之后,发出NLST命令。

在case COMMAND_NLST的处理中,先是进行了一系列的参数、权限检查,一切OK后:
 if (!m_transferstatus.pasv) // 主动模式
 {
  ...
 }
 else // 被动模式
 {
  ...
 }
由于主动模式是缺省值,因此看一下里面的代码:
CTransferSocket *transfersocket = new CTransferSocket(this);
m_transferstatus.socket = transfersocket;
transfersocket->Init(pResult, TRANSFERMODE_NLST); // 只是一些参数的初始化
if (m_transferMode == mode_zlib) // 传输方式是否使用压缩方式,缺省不使用,详细参见FTP规范
{
 if (!transfersocket->InitZLib(m_zlibLevel))
 {
  Send(_T("550 could not initialize zlib, please use MODE S instead"));
  ResetTransferstatus();
  break;
 }
}

if (!CreateTransferSocket(transfersocket)) // 建立数据连接
 break;

SendTransferinfoNotification(TRANSFERMODE_LIST, physicalDir, logicalDir); // Use TRANSFERMODE_LIST instead of TRANSFERMODE_NLST.
Send(_T("150 Opening data channel for directory list."));

先看一下建立数据连接的代码:
BOOL CControlSocket::CreateTransferSocket(CTransferSocket *pTransferSocket)
{
 ...
 if (pTransferSocket->Connect(m_transferstatus.ip,m_transferstatus.port)==0)
 ...
}
无非是常规的socket方法建立连接,需要关注的是由服务主动发起连接,这正是主动模式的含义。我们先看完这一段,再看一下被动模式。

在CreateTransferSocket()完成后,调用:

SendTransferinfoNotification(TRANSFERMODE_LIST, physicalDir, logicalDir);

看一下里面:
void CControlSocket::SendTransferinfoNotification(const char transfermode, const CStdString& physicalFile, const CStdString& logicalFile, __int64 startOffset, __int64 totalSize)
{
 t_connop *op = new t_connop;
 op->op = USERCONTROL_CONNOP_TRANSFERINIT;
 op->userid = m_userid;

 t_connectiondata_transferinfo *conndata = new t_connectiondata_transferinfo;
 conndata->transferMode = transfermode;
 conndata->physicalFile = physicalFile;
 conndata->logicalFile = logicalFile;
 conndata->startOffset = startOffset;
 conndata->totalSize = totalSize;
 op->data = conndata;

 m_pOwner->SendNotification(FSM_CONNECTIONDATA, (LPARAM)op);
}
可见发送了一个消息给CServer,wParam参数是FSM_CONNECTIONDATA,表示这是跟connection相关的消息,lParam带的参数是USERCONTROL_CONNOP_TRANSFERINIT,表示传输开始或结束,我回去看一下CServer中的OnServerMessage()相关代码,在admin窗口的下面显示了将用传输的信息。

下面,
Send(_T("150 Opening data channel for directory list."));
发送给FTP客户端数据连接创建的消息,真正的数据传输的任务是交给数据连接了,即CTransferSocket。

我们回到被动模式,如果是被动模式:
if (!m_transferstatus.pasv)
{
 ...
}
else // 被动模式
{
 ...
 m_transferstatus.socket->PasvTransfer();
}
看一下PasvTransfer()的实现:

void CTransferSocket::PasvTransfer()
{
 if(bAccepted)
  if (!m_bStarted)
   InitTransfer(FALSE);
}

非常简单,由于是被动模式,即由客户端发起数据连接,因此CTransferSocket只需等待客户端的连接就可以了,下面分析CTransferSocket的时候再仔细看一下相关的实现。

适合在Blog侧边栏玩的小游戏:【上一篇】
类和接口的设计:【下一篇】
【相关文章】
  • ftp上传下载
  • 使用CFtpconnection类实现文件的断点续传的问题
  • 一个完整的vsftp服务
  • MASK不同造成的FTP无法登陆问题
  • 创建ftpaccess文件
  • 文件传输协议(FTP)
  • [ZT]绝对经典的ftp命令大全//非常土的命令
  • 簡易 vsftpd 伺服器設定
  • vsftpd.conf 联机手册
  • 执行ftp任务Shell脚本
  • 【随机文章】
  • 封神榜 道士技能分析
  • Linux的目录结构
  • redhat7.2汉化手记
  • 一个连接池的例子 (一)
  • 对某个目录做iso文件(自己琢磨的,算原创吧)
  • initrd镜像文件的作用与制作
  • 一段根据MAC生成序列号的代码
  • 【分享】【07-22】精品软件下载
  • CIO的BI选型思路篇
  • FreeBSD系统安装及安全调整
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 bbb软讯网络 All Rigths Reserved.