天天看点

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

<a target="_blank" href="http://bbs.qter.org/forum.php?mod=viewthread&amp;tid=602">楼主</a>

[Qt教程] 第33篇 网络(三)FTP(一) [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客户端程序。下面我们先在帮助中查看这个类。

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

在qftp中,所有的操作都对应一个特定的函数,我们可以称它们为命令。如connecttohost()连接到服务器命令,login()登录命令,get()下载命令,mkdir()新建目录命令等。因为qftp类以异步方式工作,所以所有的这些函数都不是阻塞函数。也就是说,如果一个操作不能立即执行,那么这个函数就会直接返回,直到程序控制权返回qt事件循环后才真正执行,它们不会影响界面的显示。

所有的命令都返回一个int 型的编号,使用这个编号让我们可以跟踪这个命令,查看其执行状态。当每条命令开始执行时,都会发出commandstarted()信号,当该命令执行结束时,会发出commandfinished()信号。我们可以利用这两个信号和命令的编号来获取命令的执行状态。当然,如果不想执行每条命令都要记下它的编号,也可以使用currentcommand()来获取现在执行的命令,其返回值与命令的对应关系如下图。

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

下面我们先看一个简单的ftp客户端的例子,然后对它进行扩展。在这个例子中我们从ftp服务器上下载一个文件并显示出来。

1.我们新建qt gui应用。

项目名次为“myftp”,基类选择qwidget,类名保持widget即可。完成后打开muftp.pro文件,在上面添加一行:qt +=

network,然后保存该文件。

2.修改widget.ui文件。

在其中添加一个textbrowser 和一个 label,效果如下。

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

3.在main.cpp中进行修改。

为了在程序中可以使用中文,我们在main.cpp中添加头文件#include &lt;qtextcodec&gt;

并在main()函数中添加代码:

qtextcodec::setcodecfortr(qtextcodec::codecforlocale());

4.在widget.h中进行修改。

先添加头文件:#include &lt;qftp&gt;

再在private中定义对象:qftp *ftp;

添加私有槽函数:

private slots:

    void ftpcommandstarted(int);

void ftpcommandfinished(int,bool);

5.在widget.cpp中进行更改。

(1)在构造函数中添加代码:

ftp = new qftp(this);

ftp-&gt;connecttohost("ftp.qt-project.org"); //连接到服务器

ftp-&gt;login();   //登录

ftp-&gt;cd("qt/source");   //跳转到“qt”目录下的source目录中

ftp-&gt;get("install");  //下载“install”文件

ftp-&gt;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-&gt;currentcommand() == qftp::connecttohost){

       ui-&gt;label-&gt;settext(tr("正在连接到服务器..."));

    }

    if (ftp-&gt;currentcommand() == qftp::login){

       ui-&gt;label-&gt;settext(tr("正在登录..."));

    if (ftp-&gt;currentcommand() == qftp::get){

       ui-&gt;label-&gt;settext(tr("正在下载..."));

    else if (ftp-&gt;currentcommand() == qftp::close){

       ui-&gt;label-&gt;settext(tr("正在关闭连接..."));

}

每当命令执行时,都会执行ftpcommandstarted()函数,它有一个参数int id,这个id就是调用命令时返回的id,如int

loginid= ftp-&gt;login(); 这时,我们就可以用if(id == loginid)来判断执行的是否是login()函数。但是,我们不想为每个命令都设置一个变量来存储其返回值,所以,我们这里使用了ftp-&gt;currentcommand() ,它也能获取当前执行的命令的类型。在这个函数里我们让开始不同的命令时显示不同的状态信息。

void widget::ftpcommandfinished(int,bool error)

       if(error)

           ui-&gt;label-&gt;settext(tr("连接服务器出现错误:%1")

                               .arg(ftp-&gt;errorstring()));

       else ui-&gt;label-&gt;settext(tr("连接到服务器成功"));

           ui-&gt;label-&gt;settext(tr("登录出现错误:%1")

       else ui-&gt;label-&gt;settext(tr("登录成功"));

           ui-&gt;label-&gt;settext(tr("下载出现错误:%1")

       else {

           ui-&gt;label-&gt;settext(tr("已经完成下载"));

           ui-&gt;textbrowser-&gt;settext(ftp-&gt;readall());

       }

       ui-&gt;label-&gt;settext(tr("已经关闭连接"));

这个函数与ftpcommandstarted()函数相似,但是,它是在一个命令执行结束时执行的。它有两个参数,第一个intid,就是调用命令时返回的编号,我们在上面已经讲过了。第二个是bool

error,它标志现在执行的命令是否出现了错误。如果出现了错误,那么error 为true ,否则为false。我们可以利用它来输出错误信息。在这个函数中,我们在完成一条命令时显示不同的状态信息,并显示可能的出错信息。在if

(ftp-&gt;currentcommand() == qftp::get) 中,也就是已经完成下载时,我们让textbrowser显示下载的信息。

6.运行程序,效果如下。

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

7.出错演示。

下面我们演示一下出错时的情况。

将构造函数中的代码ftp-&gt;login();改为ftp-&gt;login("tom","123456");

这时我们再运行程序:

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

可以看到,它输出了错误信息,指明了错误的指令和出错的内容。其实我们设置的这个错误,也是想告诉大家,在ftp中如果没有设置用户名和密码,那么默认的用户名应该是anonymous,这时密码可以任意填写,而使用其他用户名是会出错的。

结语

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

涉及的源码下载: 

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

kb, 下载次数: 1) 

继续阅读