一、FTP基本知识

FTP 采用在主机之间建立两个 TCP 连接的方式来实现数据传输,一个连接用于控制信息的传输(命令和响应),另外一 个连接用于数据传输。

TCP通信流程

三次握手:SYN—SYN ACK—ACK

KFTPClient开发文档 - 图1

ftp控制连接

FTP连接的建立过程和普通的客户端—服务器的连接建立过程完全相同,包括一下两个步骤

  • 服务器在 TCP 的 21端口 上监听客户端连接请求(即被动打开)
  • 客户端使用一个临时端口连接到服务器的21端口上(即发起主动打开)
  • 随后在整个FTP会话过程中,控制连接一直保持,用于客户端和服务器之间进行命令的请求和应答 。

KFTPClient开发文档 - 图2

ftp数据连接

ftp数据连接主动模式:

  • 客户端通过在控制连接上发送PROT命令,告诉服务器客户端将在某个临时端口 (510000)上监听服务器的数据连接请求
  • 服务器收到PROT命令后,从20端口发送主动连接到客户端的该临时监听端口,从而建立 数据TCP连接

KFTPClient开发文档 - 图3

KFTPClient开发文档 - 图4

ftp数据连接被动模式:

  • 客户端通过在控制连接上发送PASV命令,请求服务器告诉客户端服务器将在哪个临时 端口(40000)监听客户端的数据连接请求
  • 服务器收到PASV命令后,在该临时端口上进行监听,并将监听的端口(40000)发送给 客户端,客户端从该应答中获得服务器的数据连接监听端口,然后从客户端的一个临时 发起主动连接服务器的该临时监听端口,从而建立数据TCP连接

KFTPClient开发文档 - 图5

KFTPClient开发文档 - 图6

二、KFTPClient软件设计框架

KFTPClient开发文档 - 图7

三、软件具体实现思路

  1. 软件初始运行时,需要用户输入需要使用的FTP服务器IP地址

KFTPClient开发文档 - 图8

  1. 初始化SOCKET客户端

KFTPClient开发文档 - 图9

  1. 控制连接,连接用户输入的IP(port =21)

KFTPClient开发文档 - 图10

  1. 发送OPTS命令

KFTPClient开发文档 - 图11

  1. 用户账户密码登录

KFTPClient开发文档 - 图12

  1. 用户模式选择(PASV or PORT)

KFTPClient开发文档 - 图13

KFTPClient开发文档 - 图14

当用户选择完相应的模式后,全局变量Handle就会被赋值成(0:PORT,1:PASV);

当用户选择PORT时,四种(ls, dir, get, put)模式使用数据连接的命令,会先发port包,具体来看PORT包组成:

KFTPClient开发文档 - 图15

_tcpSocket->getPortIP():获取本地计算机IP地址( “.” 替换成”,”)。getLocalIP()获取本地计算机IP地址。

KFTPClient开发文档 - 图16

m_port1与m_port2 通过真随机数计算,确保端口不会占用。

KFTPClient开发文档 - 图17

当用户选择PASV时,四种(ls, dir, get, put)模式使用数据连接的命令,会先发pasv包,具体来看PORT包组成:

KFTPClient开发文档 - 图18

当发送pasv包之后,cmdRecv会收到21端口发来的数据连接,需要解析,在本项目中通过字符串查找()和 . 实现对IP地址的查找以及”.” 替换成”,”。

KFTPClient开发文档 - 图19

KFTPClient开发文档 - 图20

KFTPClient开发文档 - 图21

  1. 进入主循环,打印帮助列表信息

KFTPClient开发文档 - 图22

  1. 用户具体使用内容

KFTPClient开发文档 - 图23

先读取、解析、发送命令,然后等待服务器回复。

KFTPClient开发文档 - 图24

KFTPClient开发文档 - 图25

KFTPClient开发文档 - 图26

  1. bye退出连接及break主循环

跳出for循环,程序结束。

KFTPClient开发文档 - 图27

  1. 文件下载

fwrite函数 elementcount参数需等于ret 而不是 sizeof(buffer),否则接收文件数据过长 当接收图片时会出现雪花。

KFTPClient开发文档 - 图28

KFTPClient开发文档 - 图29

  1. 文件上传

KFTPClient开发文档 - 图30

四、软件具体使用说明

使用前请先设置预处理器: _CRT_SECURE_NO_WARNINGS

KFTPClient开发文档 - 图31

关闭SDl检查,并设置好VLD内存泄漏检测。

KFTPClient开发文档 - 图32

  1. 登录服务器

KFTPClient开发文档 - 图33

  1. 登录账户及密码

KFTPClient开发文档 - 图34

KFTPClient开发文档 - 图35

  1. 选择模式

KFTPClient开发文档 - 图36

  1. 进入主循环 打印帮助信息

KFTPClient开发文档 - 图37

  1. ls命令

主动模式

KFTPClient开发文档 - 图38

被动模式

KFTPClient开发文档 - 图39

  1. dir命令

主动模式

KFTPClient开发文档 - 图40

被动模式

KFTPClient开发文档 - 图41

  1. get命令

主动模式

KFTPClient开发文档 - 图42

KFTPClient开发文档 - 图43

被动模式

KFTPClient开发文档 - 图44

KFTPClient开发文档 - 图45

  1. put命令

主动模式

KFTPClient开发文档 - 图46

KFTPClient开发文档 - 图47

KFTPClient开发文档 - 图48

被动模式

KFTPClient开发文档 - 图49

KFTPClient开发文档 - 图50

KFTPClient开发文档 - 图51

  1. ascii命令

KFTPClient开发文档 - 图52

  1. binary命令

KFTPClient开发文档 - 图53

  1. delete命令

KFTPClient开发文档 - 图54

KFTPClient开发文档 - 图55

  1. pwd命令

KFTPClient开发文档 - 图56

  1. cd命令

KFTPClient开发文档 - 图57

KFTPClient开发文档 - 图58

  1. mkdir命令

KFTPClient开发文档 - 图59

  1. rmdir命令

KFTPClient开发文档 - 图60

  1. bye命令

KFTPClient开发文档 - 图61

  1. 错误提示

KFTPClient开发文档 - 图62

五、分析总结

本项目中遇到了几点记忆深刻的事情:

  1. 譬如get命令,接到150 数据连接即将打开,接收数据,现在不能直接退出,要关闭socket,并接收226文件发送成功命令,否则会导致阻塞,下一个命令显示不能正常接收或者阻塞。
  2. 对于内存泄漏,对于引用的其他的类 :哪里new 哪里delete。不要放到析构函数里,否则会造成内存泄漏。

通过本项目,我对以下几点认识更加深刻:

  1. 代码规范
  2. 可复用性强,可扩展性
  3. 效率高,性能
  4. 容错, 健壮性

同时学会了使用内存泄漏检查,及性能分析工具,逐步成为一名可以胜任开发工作的c++程序员。