FileZilla FTP服务器源代码分析FileZilla是一款免费而且开源的FTP工具包括FileZilla ClientFileZilla Server两个版本FileZilla Server只提供了windows系统下的版本我们要将本地的网站网页文件上传到网站服务器或从服务器下载网页文件只需FileZilla Client客户端版本就可以了FileZilla FTP服务器源代码分在进一步分析代码之前先复习一下FTP协议下图是FTP的结构图
客户端和服务器是通过两个连接来进行通讯的
一个是控制连接也就是传输些控制命令客户端发出FTP命令服务器给出应答例如USERPASS命令等等这个连接中FTP服务器的端 口就是熟知的端口连接是由客户端发起的例如ftp 有一点注意用户是通过用户接口来操作的一般的用户接口是指cuteFTP这些FTP客户端或者ftpexe这种命令 行程序用户在用户接口使用的是ftp命令如ls get cd等这些ftp命令并不是真正与FTP服务器交互的命令这些ftp命令还需要由用户协议解释器翻译成真正的ftp协议命令如USER PASS才能与服务器进行交互
一个是数据连接即真正的文件传输是在这个连接上进行的服务器端的数据连接端口是客户端的数据连接端口是随机生成的数据连接只在传输文件 时存在文件传完后这个连接就断了如果需要再次传送文件会再次建立一个数据连接(客户端的端口是随机的不一定是上次的那个)数据连接的模式有两 种一种是主动方式一种是被动方式两者的区别在于数据连接是由谁发起
我们来看一个典型的FTP交互过程用的是windows的ftpexe程序先建立一个连接然后ls看一下文件列表用get命令下 载一个文件最后quit关闭下面d选项可以显示交互的细节注意>开头的行是ftp客户端发给FTP服务器的请求个数字开头的行是服 务器的应答如 等开头的行
C:\>ftp d localhost
Connected to dell
FileZilla Server version beta
written by Tim Kosse (TimKosse@gmxde)
Please visit
User (dell:(none)): robert
> USER robert
Password required for robert
Password:
> PASS test
Logged on
ftp> ls
> PORT
Port command successful
> NLST
Opening data channel for directory list
Manualtxt
Transfer OK
ftp: 收到 字节用时 Seconds Kbytes/sec
ftp> get Manualtxt
> PORT
Port command successful
> RETR Manualtxt
Opening data channel for file transfer
Transfer OK
ftp: 收到 字节用时 Seconds Kbytes/sec
ftp> quit
> QUIT
Goodbye
C:\>
刚开始客户端发出建立连接的请求
C:\>ftpdlocalhost//建立连接
Connectedtodell//连接已建立
然后服务器发送欢迎信息并要求输入用户名
FileZillaServerversionbeta
writtenbyTimKosse(TimKosse@gmxde)
Pleasevisit;
User(dell:(none)):
客户端输入用户名robert然后回车
> USER robert // ftpexe生成FTP命令USER发送给服务器
服务器要求输入密码
Password required for robert
Password:
客户端输入密码然后回车
> PASS test // ftpexe生成FTP命令PASS发送给服务器
服务器通过密码验证
Logged on
客户端键入ls命令
ftp> ls
ftpexe生成FTP命令PORT告诉服务器客户端的随机端口是什么
> PORT // 是IP地址 * + = 是随机端口号
Port command successful // 服务器响应PORT命令
> NLST // 客户端发出NLST命令要求列出文件列表
Opening data channel for directory list // 服务器会在端口与客户端的端口建立数据连接传输数据注意ls命令的结果是在数据连接中传输的
Manualtxt // 只有一个文件
Transfer OK // FTP服务器响应传输完毕
ftp: 收到 字节用时 Seconds Kbytes/sec // FTP客户端显示的传输结果
下面客户端要求下载Manualtxt文件
ftp> get Manualtxt
> PORT // 告诉服务器客户端新的随机端口 * + =
Port command successful // // 服务器响应PORT命令
> RETR Manualtxt // 告诉服务器下载Manualtxt文件
Opening data channel for file transfer // 服务器会在端口与客户端的端口建立数据连接传输数据
Transfer OK // FTP服务器响应传输完毕
ftp: 收到 字节用时 Seconds Kbytes/sec // FTP客户端显示的传输结果
最后客户端退出
ftp> quit
> QUIT // 发出QUIT命令
Goodbye // 服务器最后响应
仔细阅读上面的交互过程可以发现用户手工输入的一个FTP命令可能会被ftpexe处理成与FTP服务器的多次交互如ls get命令
要想详细了解FTP命令的细节可以参见FTP的RFC或者相关的资料不过由于我们阅读源代码的主要目的不是研究FTP细节而在于掌握高并发的网络编程的技术所以我们只以上面这个简单的FTP交互来看一下在代码中这个过程是如何实现的