最近在做iot的项目,发现要在iot上启动一个ftps的客户端。这个和之前在linux上实现一个ftp客户端不一样。在linux上,还是有很多开源软件寻找的。但是对于一般的iot项目,芯片是无法像一般的路由芯片一样可以加内存,所以在资源还是比较紧张的。所以打算自己实现一个简单的ftps client。 
这里写图片描述


FTP属于协议的哪有一层 
ftp是基于tcp/ip上层的,属于应用协议。 
这里写图片描述

FTP工作模式 
FTP 通讯有两种模式:主动模式(Port) 以及 被动模式(Passive)

  1. 主动模式(Port):FTP 客户端首先和FTP服务器的TCP 21端口建立连接,通过这个通道发送命令,客户端需要接收数据的时候在这个通道上发送PORT命令。 PORT命令包含了客户端用什么端口接收数据。在传送数据的时候,服务器端通过自己的TCP 20端口连接至客户端的指定端口发送数据。 FTP server必须和客户端建立一个新的连接用来传送数据。 
    这里写图片描述

  2. 被动模式(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被动模式一个完整的流程抓包: 
这里写图片描述

posted on 2018-05-21 16:47  JasonChen1030  阅读(462)  评论(0编辑  收藏  举报