[Qt教程] 第33篇 网络(三)FTP(一)

楼主

 发表于 2013-9-4 14:52:46 | 查看: 392| 回复: 8
FTP(一)
版权声明

该文章原创于作者yafeilinux,转载请注明出处!
导语

上一节我们讲述了HTTP的编程,这一节讲述与其及其相似的FTP的编程。FTP即FileTransfer Protocol,也就是文件传输协议。FTP的主要作用,就是让用户连接上一个远程计算机,查看远程计算机有哪些文件,然后把文件从远程计算机上拷贝到本地计算机,或者把本地计算机的文件送到远程计算机上。
环境:Windows Xp + Qt 4.8.5+QtCreator 2.8.0
目录

一、简介
二、实现简单的文件下载
正文

一、简介
在Qt中,我们可以使用上一节讲述的QNetworkAccessManager和QNetworkReply类来进行FTP 程序的编写,因为它们用起来很简单。但是,对于较复杂的FTP操作,Qt还提供了QFtp类,利用这个类,我们很容易写出一个FTP客户端程序。下面我们先在帮助中查看这个类。
在QFtp中,所有的操作都对应一个特定的函数,我们可以称它们为命令。如connectToHost()连接到服务器命令,login()登录命令,get()下载命令,mkdir()新建目录命令等。因为QFtp类以异步方式工作,所以所有的这些函数都不是阻塞函数。也就是说,如果一个操作不能立即执行,那么这个函数就会直接返回,直到程序控制权返回Qt事件循环后才真正执行,它们不会影响界面的显示。
所有的命令都返回一个int 型的编号,使用这个编号让我们可以跟踪这个命令,查看其执行状态。当每条命令开始执行时,都会发出commandStarted()信号,当该命令执行结束时,会发出commandFinished()信号。我们可以利用这两个信号和命令的编号来获取命令的执行状态。当然,如果不想执行每条命令都要记下它的编号,也可以使用currentCommand()来获取现在执行的命令,其返回值与命令的对应关系如下图。
二、实现简单的文件下载
下面我们先看一个简单的FTP客户端的例子,然后对它进行扩展。在这个例子中我们从FTP服务器上下载一个文件并显示出来。
1.我们新建Qt Gui应用。
项目名次为“myFtp”,基类选择QWidget,类名保持Widget即可。完成后打开muFtp.pro文件,在上面添加一行:QT += network,然后保存该文件。
2.修改widget.ui文件。
在其中添加一个TextBrowser 和一个 Label,效果如下。
3.在main.cpp中进行修改。
为了在程序中可以使用中文,我们在main.cpp中添加头文件#include <QTextCodec>
并在main()函数中添加代码:
QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
4.在widget.h中进行修改。
先添加头文件:#include <QFtp>
再在private中定义对象:QFtp *ftp;
添加私有槽函数:
private slots:
    void ftpCommandStarted(int);
void ftpCommandFinished(int,bool);
5.在widget.cpp中进行更改。
(1)在构造函数中添加代码:
  1. ftp = new QFtp(this);
  2. ftp->connectToHost("ftp.qt-project.org"); //连接到服务器
  3. ftp->login();   //登录
  4. ftp->cd("qt/source");   //跳转到“qt”目录下的source目录中
  5. ftp->get("INSTALL");  //下载“INSTALL”文件
  6. ftp->close();   //关闭连接
  7. // 当每条命令开始执行时发出相应的信号
  8. connect(ftp,SIGNAL(commandStarted(int)),
  9. this,SLOT(ftpCommandStarted(int)));
  10. // 当每条命令执行结束时发出相应的信号
  11. connect(ftp,SIGNAL(commandFinished(int,bool)),
  12. this,SLOT(ftpCommandFinished(int,bool)));

复制代码

我们在构造函数里执行了几个FTP的操作,登录站点,并下载了一个文件。然后又关联了两个信号和槽,用来跟踪命令的执行情况。
(2)实现槽函数:
void Widget::ftpCommandStarted(int)
{
    if(ftp->currentCommand() == QFtp::ConnectToHost){
       ui->label->setText(tr("正在连接到服务器..."));
    }
    if (ftp->currentCommand() == QFtp::Login){
       ui->label->setText(tr("正在登录..."));
    }
    if (ftp->currentCommand() == QFtp::Get){
       ui->label->setText(tr("正在下载..."));
    }
    else if (ftp->currentCommand() == QFtp::Close){
       ui->label->setText(tr("正在关闭连接..."));
    }
}
每当命令执行时,都会执行ftpCommandStarted()函数,它有一个参数int id,这个id就是调用命令时返回的id,如int loginID= ftp->login(); 这时,我们就可以用if(id == loginID)来判断执行的是否是login()函数。但是,我们不想为每个命令都设置一个变量来存储其返回值,所以,我们这里使用了ftp->currentCommand() ,它也能获取当前执行的命令的类型。在这个函数里我们让开始不同的命令时显示不同的状态信息。
void Widget::ftpCommandFinished(int,bool error)
{
    if(ftp->currentCommand() == QFtp::ConnectToHost){
       if(error)
           ui->label->setText(tr("连接服务器出现错误:%1")
                               .arg(ftp->errorString()));
       else ui->label->setText(tr("连接到服务器成功"));
    }
    if (ftp->currentCommand() == QFtp::Login){
       if(error)
           ui->label->setText(tr("登录出现错误:%1")
                               .arg(ftp->errorString()));
       else ui->label->setText(tr("登录成功"));
    }
    if (ftp->currentCommand() == QFtp::Get){
       if(error)
           ui->label->setText(tr("下载出现错误:%1")
                               .arg(ftp->errorString()));
       else {
           ui->label->setText(tr("已经完成下载"));
           ui->textBrowser->setText(ftp->readAll());
       }
    }
    else if (ftp->currentCommand() == QFtp::Close){
       ui->label->setText(tr("已经关闭连接"));
    }
}
这个函数与ftpCommandStarted()函数相似,但是,它是在一个命令执行结束时执行的。它有两个参数,第一个intid,就是调用命令时返回的编号,我们在上面已经讲过了。第二个是bool error,它标志现在执行的命令是否出现了错误。如果出现了错误,那么error 为true ,否则为false。我们可以利用它来输出错误信息。在这个函数中,我们在完成一条命令时显示不同的状态信息,并显示可能的出错信息。在if (ftp->currentCommand() == QFtp::Get) 中,也就是已经完成下载时,我们让textBrowser显示下载的信息。
6.运行程序,效果如下。
7.出错演示。
下面我们演示一下出错时的情况。
将构造函数中的代码ftp->login();改为ftp->login("tom","123456");
这时我们再运行程序:
可以看到,它输出了错误信息,指明了错误的指令和出错的内容。其实我们设置的这个错误,也是想告诉大家,在FTP中如果没有设置用户名和密码,那么默认的用户名应该是anonymous,这时密码可以任意填写,而使用其他用户名是会出错的。
结语

在下一节中,我们将会对这个程序进行扩展,让它可以浏览服务器上的所有文件,并进行下载。


涉及的源码下载:  myFtp1.rar (2.09 KB, 下载次数: 1)

[Qt教程] 第33篇 网络(三)FTP(一)相关推荐

  1. [Qt教程] 第34篇 网络(四)FTP(二)

    [Qt教程] 第34篇 网络(四)FTP(二) 楼主  发表于 2013-9-4 15:04:38 | 查看: 315| 回复: 9 FTP(二) 版权声明 该文章原创于作者yafeilinux,转载 ...

  2. [Qt教程] 第39篇 网络(九)进程和线程

    [Qt教程] 第39篇 网络(九)进程和线程 楼主  发表于 2013-8-29 15:48:56 | 查看: 415| 回复: 0 进程和线程 版权声明 该文章原创于作者yafeilinux,转载请 ...

  3. [Qt教程] 第38篇 网络(八)TCP(二)

    [Qt教程] 第38篇 网络(八)TCP(二) 楼主  发表于 2013-9-6 15:50:35 | 查看: 421| 回复: 3 TCP(二) 版权声明 该文章原创于作者yafeilinux,转载 ...

  4. [Qt教程] 第35篇 网络(五)获取本机网络信息

    [Qt教程] 第35篇 网络(五)获取本机网络信息 楼主  发表于 2013-9-5 11:32:58 | 查看: 278| 回复: 2 获取本机网络信息 版权声明 该文章原创于作者yafeilinu ...

  5. [Qt教程] 第32篇 网络(二)HTTP

    [Qt教程] 第32篇 网络(二)HTTP 楼主  发表于 2013-8-28 17:21:28 | 查看: 637| 回复: 8 HTTP 版权声明 该文章原创于作者yafeilinux,转载请注明 ...

  6. [Qt教程] 第40篇 网络(十)WebKit初识

    [Qt教程] 第40篇 网络(十)WebKit初识 楼主  发表于 2013-9-11 17:26:05 | 查看: 521| 回复: 10 WebKit初识 版权声明 该文章原创于作者yafeili ...

  7. [Qt教程] 第37篇 网络(七)TCP(一)

    [Qt教程] 第37篇 网络(七)TCP(一) 楼主  发表于 2013-9-6 15:44:45 | 查看: 398| 回复: 1 TCP (一) 版权声明 该文章原创于作者yafeilinux,转 ...

  8. [Qt教程] 第36篇 网络(六)UDP

    [Qt教程] 第36篇 网络(六)UDP 楼主  发表于 2013-9-5 11:38:50 | 查看: 241| 回复: 0 UDP 版权声明 该文章原创作者yafeilinux,转载请注明出处! ...

  9. [Qt教程] 第31篇 网络(一)Qt网络编程简介

    [Qt教程] 第31篇 网络(一)Qt网络编程简介 楼主  发表于 2013-8-28 17:04:17 | 查看: 515| 回复: 0 Qt网络编程简介 版权声明 该文章原创于作者yafeilin ...

最新文章

  1. new com.mysql.jdbc.Driver()为什么Driver会创建两次
  2. 数据中台实战(四):商品分析(产品设计篇)
  3. Vue+Openlayers实现加载天地图WMTS服务显示
  4. TMS320F28335时钟(1)
  5. Nginx 0.8.5版本access.log日志分析shell命令
  6. linux服务器指示灯,【转】明明白白你的Linux服务器——故障篇 | 旺旺知识库
  7. 2.3 基本算法之递归变递推 1188 菲波那契数列(2) python
  8. c语言程序设计ns图怎么画,请各位大神帮个忙,画个NS流程图,,急!!!
  9. Agisoft Metashape照片转3D模型打印拿宇树狗做个实验
  10. 更换光猫后网速变慢的解决办法
  11. 【2023校招刷题】常见面试问题总结(一、EDA工具及IC整体设计流程篇)(随后续面试不断更新....)
  12. Python27 No module named PIL解决方法
  13. Android面试之计算机网络基础
  14. 机器学习 数据集划分 训练集 验证集 测试集
  15. 基于Pytorch实现的声纹识别模型
  16. eclipse java1.8_不同版本Eclipse对JDK版本要求
  17. 7-4 单链表基本操作
  18. 网络系统设计的基本原则(一)
  19. 每日分享(采集网站访客流量统计程序)
  20. Java多线程系列-CyclicBarrier

热门文章

  1. 关于:以前的某个程序安装已在安装计算机上创建挂起的文件操作解决办法(SQL2000)...
  2. vrep和matlab,VREP与MATLAB联合仿真程序--UR5机械臂动力学控制
  3. android汉字笔顺数据库,Chinese stroke order app
  4. starting mysql. success!_启动mysql报错解决问题过程
  5. python tcl quartus_TCL脚本在Quartus II中的应用
  6. Mac关于Node版本升降
  7. 优酷土豆2012.9.12校园招聘会笔试题
  8. Eclipse 常用快捷键-java
  9. (转)Linux内核参数之arp_ignore和arp_announce
  10. SQL Server 中系统视图sysobjects中type字段的说明