最近在做iot的项目,发现要在iot上启动一个ftps的客户端。这个和之前在linux上实现一个ftp客户端不一样。在linux上,还是有很多开源软件寻找的。但是对于一般的iot项目,芯片是无法像一般的路由芯片一样可以加内存,所以在资源还是比较紧张的。所以打算自己实现一个简单的ftps client。
FTP属于协议的哪有一层
ftp是基于tcp/ip上层的,属于应用协议。
FTP工作模式
FTP 通讯有两种模式:主动模式(Port) 以及 被动模式(Passive)
-
主动模式(Port):FTP 客户端首先和FTP服务器的TCP 21端口建立连接,通过这个通道发送命令,客户端需要接收数据的时候在这个通道上发送PORT命令。 PORT命令包含了客户端用什么端口接收数据。在传送数据的时候,服务器端通过自己的TCP 20端口连接至客户端的指定端口发送数据。 FTP server必须和客户端建立一个新的连接用来传送数据。
-
被动模式(Passive):Passive模式在建立控制通道的时候和Standard模式类似,但建立连接后发送的不是Port命令,而是Pasv命令。FTP服务器收到Pasv命令后,随机打开一个高端端口(端口号大于1024)并且通知客户端在这个端口上传送数据的请求,客户端连接FTP服务器此端口,然后FTP服务器将通过这个端口进行数据的传送,这个时候FTP server不再需要建立一个新的和客户端之间的连接。
FTP响应码
110: 重新启动标记应答。
120: 在n分钟内准备好
125: 连接打开准备传送
150: 打开数据连接
200: 命令成功
202: 命令失败
211: 系统状态
212: 目录状态
213: 文件状态
214: 帮助信息
215: 名字系统类型
220: 新用户服务准备好了
221: 服务关闭控制连接,可以退出登录
225: 数据连接打开,无传输正在进行
226: 关闭数据连接,请求的文件操作成功
227: 进入被动模式
230: 用户登录
250: 请求的文件操作完成
257: 创建”PATHNAME”
331: 用户名正确,需要口令
332: 登录时需要帐户信息
350: 下一步命令
421: 不能提供服务,关闭控制连接
425: 不能打开数据连接
426: 关闭连接,中止传输
450: 请求的文件操作未执行
451: 中止请求的操作:有本地错误
452: 未执行请求的操作:系统存储空间不足
500: 格式错误,命令不可识别
501: 参数语法错误
502: 命令未实现
503: 命令顺序错误
504: 此参数下的命令功能未实现
530: 未登录
532: 存储文件需要帐户信息
550: 未执行请求的操作
551: 请求操作中止:页类型未知
552: 请求的文件操作中止,存储分配溢出
553: 未执行请求的操作:文件名不合法
FTP术语
150 文件状态良好,打开数据连接
200 命令成功
202 命令未实现
211 系统状态或系统帮助响应
212 目录状态
213 文件状态
214 帮助信息,信息仅对人类用户有用
215 名字系统类型
220 对新用户服务准备好
221 服务关闭控制连接,可以退出登录
225 数据连接打开,无传输正在进行
226 关闭数据连接,请求的文件操作成功
227 进入被动模式
230 用户登录
250 请求的文件操作完成
257 创建”PATHNAME”
331 用户名正确,需要口令
332 登录时需要帐户信息
350 请求的文件操作需要进一步命令
421 连接用户过多
425 不能打开数据连接
426 关闭连接,中止传输
450 请求的文件操作未执行
451 中止请求的操作:有本地错误
452 未执行请求的操作:系统存储空间不足
500 格式错误,命令不可识别
501 参数语法错误
502 命令未实现
503 命令顺序错误
504 此参数下的命令功能未实现
530 账号或密码错误
532 存储文件需要帐户信息
550 未执行请求的操作
551 请求操作中止:页类型未知
552 请求的文件操作中止,存储分配溢出
553 未执行请求的操作:文件名不合法
FTP交互命令
命令 描述
ABOR : 中断数据连接程序
ACCT : 系统特权帐号
ALLO : 为服务器上的文件存储器分配字节
APPE : 添加文件到服务器同名文件
CDUP : 改变服务器上的父目录
CWD : 改变服务器上的工作目录
DELE : 删除服务器上的指定文件
HELP : 返回指定命令信息
LIST : 如果是文件名列出文件信息,如果是目录则列出文件列表
MODE : 传输模式(S=流模式,B=块模式,C=压缩模式)
MKD : 在服务器上建立指定目录
NLST : 列出指定目录内容
NOOP : 无动作,除了来自服务器上的承认
PASS : 系统登录密码
PASV : 请求服务器等待数据连接
PORT : IP 地址和两字节的端口 ID
PWD : 显示当前工作目录
QUIT : 从 FTP 服务器上退出登录
REIN : 重新初始化登录状态连接
REST : 由特定偏移量重启文件传递
RETR : 从服务器上找回(复制)文件
RMD : 在服务器上删除指定目录
RNFR : 对旧路径重命名
RNTO : 对新路径重命名
SITE : 由服务器提供的站点特殊参数
SMNT : 挂载指定文件结构
STAT : 在当前程序或目录上返回信息
STOR : 储存(复制)文件到服务器上
STOU : 储存文件到服务器名称上
STRU : 数据结构(F=文件,R=记录,P=页面)
SYST : 返回服务器使用的操作系统
TYPE : 数据类型(A=ASCII,E=EBCDIC,I=binary)
USER : 系统登录的用户名
关于这两种模式,就会有一个问题了。在实际中,我们应该如何选中哪种模式呢?
针对以上的疑问,进行分析:
由于防火墙的原因,外网的服务器是无法访问内网的PC的。
当我们的服务器部署到外网,设备在内网的时候。我们必须使用被动模式。
在代码上的实现方式是,按照上图的 ftp_port & ftp_passive 的流程,在建立起TCP链接的条件下,发送响应的cmd,并根据对端cmd做相应的响应即可。
以下为FTP被动模式一个完整的流程抓包: