自从Qt5删除了QFtp模块后,就没有了可方便使用的FTP类。根据官方的说法,是因为该模块实现质量不好被删除,而用Qt5的网络模块就可以轻松实现。对于初学者没了现成的工具就不知道该咋办了。本文从FTP协议开始讲起,先明白FTP协议是一个怎样的结构。然后讲解如何用代码去实现。

全文分两大部分,第一部分是FTP协议的讲解,第二部分是Qt5的代码实现。笔者会尽量用简洁明了的语句给列为讲清楚的,让我们开始吧~~

  1. FTP协议
  2. Qt5的代码实现

第一部分 FTP协议

什么是FTP协议?

就是传文件用的协议。整个过程就是先用TCP与服务器建立连接,然后发送命令,服务器执行并进行反馈。

FTP的两个端口

一般的客户端/服务器之间是开一个Socket端口,既传输命令又传输数据。而FTP的协议中说:我要开两个端口,一个传输命令,一个传输数据。

  • 传输命令端口(21)
  • 传输数据端口(20)

所以在编程的时候要创建两个QTcpSocket哦~

FTP的两种过程

分为被动模式和主动模式。这是从客户端的角度来说的。比如常见的被动模式意思就是服务器告诉你我们用哪个端口进行数据传输,我们(客户端)没有指定端口的权力,它(服务器)说用啥端口我们(客户端)就用啥端口。

而主动模式就是我们(客户端)自己定好用哪个端口,告诉了服务器,然后双方在这个端口下进行通信。

  • 被动模式(常用)

根据上文所述,既然都“被动”了,那我们客户端就等着服务器给我们分配端口号吧。

(1)首先我们任意打开一个端口N连接FTP服务器,并在Socket中写“PASV”命令。这里的N必须大于1024;

(2)然后服务器会返回个信息,类似“227 Entering Passive Mode(47,94,99,120,39,18)”这样。前四个是服务器IP地址,后两个是和分配的端口号相关的数。从这条信息我们就知道了服务器给我们分配的用于数据传输的端口号是:39*256+18;

(3)然后我们就打开第二个端口N+1和服务器的这个39*256+18端口进行连接,然后数据传输。

  • 主动模式

根据上文所述,既然都“主动”了,那我们客户端就自由分配进行数据传输的端口号吧。

(1)第一步还是任意打开两个端口N和N+1,先用N端口连接FTP服务器的21端口,同时第二个端口N+1进行监听。在第一个端口发送“port N+1”命令;

(2)这时服务器就会主动连接到我们的N+1端口上了。

FTP命令及响应码

FTP命令

命令字符串结尾要加'\n'

  • ABOR:中断数据连接程序
  • ACCT <account>:系统特权帐号
  • ALLO <bytes>:为服务器上的文件存储器分配字节
  • APPE <filename>:添加文件到服务器同名文件
  • CDUP <dir path>:改变服务器上的父目录
  • CWD <dir path>:改变服务器上的工作目录
  • DELE <filename>:删除服务器上的指定文件
  • HELP <command>:返回指定命令信息
  • LIST <name>:如果是文件名列出文件信息,如果是目录则列出文件列表
  • MODE <mode>:传输模式(S=流模式,B=块模式,C=压缩模式)
  • MKD <directory>:在服务器上建立指定目录
  • NLST <directory>:列出指定目录内容
  • NOOP:无动作,除了来自服务器上的承认
  • PASS <password>:系统登录密码
  • PASV:请求服务器等待数据连接
  • PORT <address>:IP 地址和两字节的端口 ID
  • PWD:显示当前工作目录
  • QUIT:从 FTP 服务器上退出登录
  • REIN:重新初始化登录状态连接
  • REST <offset>:由特定偏移量重启文件传递
  • RETR <filename>:从服务器上找回(复制)文件
  • RMD <directory>:在服务器上删除指定目录
  • RNFR <old path>:对旧路径重命名
  • RNTO <new path>:对新路径重命名
  • SITE <params>:由服务器提供的站点特殊参数
  • SMNT <pathname>:挂载指定文件结构
  • STAT <directory>:在当前程序或目录上返回信息
  • STOR <filename>:储存(复制)文件到服务器上
  • STOU <filename>:储存文件到服务器名称上
  • STRU <type>:数据结构(F=文件,R=记录,P=页面)
  • SYST:返回服务器使用的操作系统
  • TYPE <data type>:数据类型(A=ASCII,E=EBCDIC,I=binary)
  • USER <username>:系统登录的用户名

FTP响应码

  • 110:新文件指示器上的重启标记
  • 120:服务器准备就绪的时间(分钟数)
  • 125:打开数据连接,开始传输
  • 150:打开连接
  • 200:成功
  • 202:命令没有执行
  • 211:系统状态回复
  • 212:目录状态回复
  • 213:文件状态回复
  • 214:帮助信息回复
  • 215:系统类型回复
  • 220:服务就绪
  • 221:退出网络
  • 225:打开数据连接
  • 226:结束数据连接
  • 227:进入被动模式(IP 地址、ID 端口)
  • 230:登录因特网
  • 250:文件行为完成
  • 257:路径名建立
  • 331:要求密码
  • 332:要求帐号
  • 350:文件行为暂停
  • 421:服务关闭
  • 425:无法打开数据连接
  • 426:结束连接
  • 450:文件不可用
  • 451:遇到本地错误
  • 452:磁盘空间不足
  • 500:无效命令
  • 501:错误参数
  • 502:命令没有执行
  • 503:错误指令序列
  • 504:无效命令参数
  • 530:未登录网络
  • 532:存储文件需要帐号
  • 550:文件不可用
  • 551:不知道的页类型
  • 552:超过存储分配
  • 553:文件名不允许

第二部分 FTP的Qt5的代码实现

网络编程三步骤:Socket连接、Write/Read读写、Close关闭

  • 被动模式的代码实现

一般的服务器都是采用被动模式,所以先讲解这部分。

1/3 Socket连接

/* 构造Socket,并连接 */
socket = new QTcpSocket(this);
connect(socket,&QTcpSocket::connected,this,&MainWindow::slotConnected);
connect(socket,&QTcpSocket::readyRead,this,&MainWindow::dataReceived);
socket->connectToHost("47.94.99.120",21);

有两个槽,slotConnected()槽的作用是如果Socket和服务器建立连接,就在textEdit上显示“已建立Socket连接”的字样;dataeceived()槽的作用是显示服务器反馈回来的信息。

  • void slotConnected()槽
void MainWindow::slotConnected()
{ui->textEdit->append("已建立Socket连接");
}
  • void dataReceived()槽
void MainWindow::dataReceived()
{while (socket->bytesAvailable()){/* 读取Socket并存入datagram */QByteArray datagram = socket->readAll();/* 展示在textEdit */QString str = QString::fromLocal8Bit(datagram);ui->textEdit->append(str);}
}

看下效果:

通过连接,服务器反馈回“220 (vsFTPd 3.0.2)”的信息。由上文所述,220响应码的含义是“服务就绪”。那么接下来就是write/read过程了。

2/3 Write/Read读写

“发送命令”按钮的代码:

void MainWindow::on_pbSend_clicked()
{QByteArray command = ui->lineEdit->text().toLatin1();command += '\n';socket->write(command);
}

注意:命令结尾不要忘了加个'\n'回车符号。

发送 USEuser_name 用户名

发送 PASS xxxxxxx 密码

发送 PASV 命令

到此为止,服务器给我们回复“227 Entering Passive Mode(47,94,99,120,39,16)”的响应码,这是要告诉我们“应该采用被动模式”,后面还附带了服务器IP地址,以及两个变量。通过计算得知,服务器给我们分配的数据传输端口号是:39*256+16=10000。

接下来就是再构造一个Socket,端口号为10000,去连接服务器的20端口号(传输数据用)。然后各种命令,接受的文件也用Socket的read()等函数去接受,然后QFile各种存文件操作等等等等。


接下来的步骤就不写了,FTP协议属于应用层的部分,具体如何按照这个标准去组织语言就是列位发挥的部分了。

刚开始我写FTP协议的时候摸不着头脑,也不懂HTTP协议、FTP协议等内容,后来经过摸索才知道:哦,这就是应用层的东西。人家都已经告诉你如何去实现FTP的过程了,我们就照着这个过程写程序就是咯。

所以整个过程还是很简单的,就是用Socket去你来我往的交流而已,没有涉及多么高大上的东西。FTP协议很简单吧~

Qt5.10编写FTP客户端相关推荐

  1. 明明白白用Qt5.10编写FTP客户端

    使用Linux自带工具实现定时下载FTP文件(文末) 前言 自从Qt5删除了QFtp模块后,就没有了可方便使用的FTP类.根据官方的说法,是因为该模块实现质量不好被删除,而用Qt5的网络模块就可以轻松 ...

  2. 18. 编写FTP客户端程序

    在实际应用中可能经常访问FTP服务器来上传或下载文件,Python也可以替我们做这些. [示例 1]下面请看一个例子(ftpclient). 运行的结果如下: FTP客户端程序的编写还可以参照官方文档 ...

  3. python编写ftp客户端_用Python写FTP客户端程序

    0 前言: ftp客户端相信大家都用过,那么我们为什么还要用Python写ftp客户端呢? 我想有两个原因: 一是写出更好的ftp客户端应用程序,方便大家使用: 二是定制一些特殊服务,例如每天定时下载 ...

  4. python ftplib_python:使用ftplib编写FTP客户端

    Python中的ftplib模块 Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实现简单的ftp客户端,用于上传或下载文件 FTP的工作流程及基本操作可参考协议RFC95 ...

  5. python编写ftp客户端_python实现ftp客户端示例分享

    代码如下: #!/usr/bin/python #coding:utf-8 #write:JACK #info:ftp example import ftplib, socket, os from t ...

  6. Qt5.10编写俄罗斯方块

    一.先看效果图 二.主要的设计思路: 1.采用Qt的QGraphicsScene.QGraphicsScene.QGraphicsItem实现界面的绘制: 2.对每一种类型的方块单独设计一个类,所有类 ...

  7. paho | 支持10种语言编写mqtt客户端,总有一款适合你!

    1. 轻量级物联网协议 - MQTT MQTT全称 Message Queuing Telemetry Transport,即消息队列遥测传输协议,是一种基于发布/订阅(publish/subscri ...

  8. C#毕业设计——基于C#+asp.net+FTP的FTP客户端设计与实现(毕业论文+程序源码)——FTP客户端

    基于C#+asp.net+FTP的FTP客户端设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于C#+asp.net+FTP的FTP客户端设计与实现,文章末尾附有本毕业设计的论文和源码下载地 ...

  9. FTP客户端设计与实现

    互联网的一大特点是实现信息共享,文件传输是信息共享的十分重要的内容之一.随之出现了许多FTP服务器来共享一些信息资源,编写一个操作简单,方便的FTP客户端来下载这些资源受到了人们的极大欢迎. FTP客 ...

  10. 基于java的ftp客户端_基于Java的FTP客户端软件的设计

    基于的FTP客户端软件的设计(含选题审批表,任务书,开题报告,中期检查表,毕业论文8600字,答辩记录) 摘 要:FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中 ...

最新文章

  1. 正式迁移博客到osc
  2. VMware发布新版vSphere6.5虚拟化平台,助力企业数字化转型
  3. python open文件安全隐患_python的其他安全隐患
  4. gwt格式_GWT –利弊
  5. JavaScript 获取当日在今年第几周
  6. 鸟瞰 MySQL,唬住面试官!
  7. 一款“灵动”的滑动按钮
  8. java web 收发邮件_Java总结(五)之实现javaweb发送邮件
  9. 基于SSM实现毕业设计管理系统
  10. 工程学导论——心得体会
  11. 【第三方服务】微信公众平台授权登录
  12. 【java】解决安装时时显示this version of the jdk is already installed……
  13. SpringBoot集成Activiti
  14. 会声会影应该如何制作电影开幕效果
  15. L0,L1,L2正则化浅析
  16. 如何用new定义二维数据以及对应的delete
  17. 最常用的几个数据验证正则判断,手机号,车牌号,身份证,Email,IP
  18. 【子网划分】求子网网络前缀、子网地址、每个子网可以分配给主机使用的最小地址和最大地址
  19. mysql 视图 事务 存储过程 触发器——龙腾
  20. MSP432的SPI通信模式

热门文章

  1. ensp查看历史配置命令_学习华为ensp基本命令小技巧
  2. Quartus II 13.0 最全的安装、破解教程(包含下载地址)
  3. Ubuntu下VLC播放器安装配置以及VLC常用快捷键记录
  4. Word VBA:批量删除多个分段页面
  5. 小白能读懂的 《手把手教你学DSP(TMS320X281X)》第四章(2) gel文件
  6. WIN7 32 联想针式打印机 联想DP600+ 文字不全
  7. C#常用 API函数大全
  8. 软件开发外包项目常见的问题
  9. springdata elasticsearch aggregation 操作
  10. armv6, armv7, armv7s, arm64 的区别