设为首页 收藏本站
查看: 1073|回复: 0

[经验分享] 四十三、Qt网络(三)FTP(一)

[复制链接]

尚未签到

发表于 2016-6-9 06:10:39 | 显示全部楼层 |阅读模式
  上一节我们讲述了HTTP的编程,这一节讲述与其及其相似的FTP的编程。FTP即File Transfer Protocol,也就是文件传输协议。FTP的主要作用,就是让用户连接上一个远程计算机,查看远程计算机有哪些文件,然后把文件从远程计算机上拷贝到本地计算机,或者把本地计算机的文件送到远程计算机上。
  在Qt中,我们可以使用上一节讲述的QNetworkAccessManager和QNetworkReply类来进行FTP 程序的编写,因为它们用起来很简单。但是,对于较复杂的FTP操作,Qt还提供了QFtp类,利用这个类,我们很容易写出一个FTP客户端程序。下面我们先在帮助中查看这个类。
http://j.imagehost.org/0896/1_40.jpg
  在QFtp中,所有的操作都对应一个特定的函数,我们可以称它们为命令。如connectToHost()连接到服务器命令,login()登录命令,get()下载命令,mkdir()新建目录命令等。因为QFtp类以异步方式工作,所以所有的这些函数都不是阻塞函数。也就是说,如果一个操作不能立即执行,那么这个函数就会直接返回,直到程序控制权返回Qt事件循环后才真正执行,它们不会影响界面的显示。
  所有的命令都返回一个int 型的编号,使用这个编号让我们可以跟踪这个命令,查看其执行状态。当每条命令开始执行时,都会发出commandStarted()信号,当该命令执行结束时,会发出commandFinished()信号。我们可以利用这两个信号和命令的编号来获取命令的执行状态。当然,我们不想执行每条命令都要记下它的编号,所以我们也可以使用currentCommand()来获取现在执行的命令,其返回值与命令的对应关系如下图。
http://h.imagehost.org/0890/2_31.jpg
  下面我们先看一个简单的FTP客户端的例子,然后对它进行扩展。
  在这个例子中我们从FTP服务器上下载一个文件并显示出来。
  1.我们新建Qt4 Gui QApplication
  工程名为“myFtp”,然后选中QtNetwork模块,最后Base class选择QWidget 。
  2.修改widget.ui文件。
  在其中添加一个Text Browser 和一个 Label,效果如下。
http://h.imagehost.org/0293/3_14.jpg
  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)在构造函数中添加代码:
  ftp = new QFtp(this);
  ftp->connectToHost(“ftp.qt.nokia.com”); //连接到服务器
  ftp->login(); //登录
  ftp->cd(“qt”); //跳转到“qt”目录下
  ftp->get(“INSTALL”); //下载“INSTALL”文件
  ftp->close(); //关闭连接
  connect(ftp,SIGNAL(commandStarted(int)),
  this,SLOT(ftpCommandStarted(int)));
  //当每条命令开始执行时发出相应的信号
  connect(ftp,SIGNAL(commandFinished(int,bool)),
  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()函数相似,但是,它是在一个命令执行结束时执行的。它有两个参数,第一个int id,就是调用命令时返回的编号,我们在上面已经讲过了。第二个是bool error,它标志现在执行的命令是否出现了错误。如果出现了错误,那么error 为true ,否则为false。我们可以利用它来输出错误信息。在这个函数中,我们在完成一条命令时显示不同的状态信息,并显示可能的出错信息。在if (ftp->currentCommand() == QFtp::Get) 中,也就是已经完成下载时,我们让textBrowser显示下载的信息。
  6.运行程序,效果如下。
  登录状态。
  http://a.imagehost.org/0206/4_26.jpg
  下载完成后。
http://a.imagehost.org/0497/5_38.jpg
  7.出错演示。
  下面我们演示一下出错时的情况。
  将构造函数中的代码ftp->login();改为ftp->login(“tom”,”123456″);
  这时我们再运行程序:
http://a.imagehost.org/0391/6_18.jpg
  可以看到,它输出了错误信息,指明了错误的指令和出错的内容。其实我们设置的这个错误,也是想告诉大家,在FTP中如果没有设置用户名和密码,那么默认的用户名应该是anonymous,这时密码可以任意填写,而使用其他用户名是会出错的。
   在下一节中,我们将会对这个程序进行扩展,让它可以浏览服务器上的所有文件,并进行下载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-227948-1-1.html 上篇帖子: (转)ftp的port和pasv模式 下篇帖子: FTP的主动模式和被动模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表