ImageVerifierCode 换一换
格式:DOCX , 页数:12 ,大小:22.54KB ,
资源ID:6079908      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6079908.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Qt的FTP网络编程.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Qt的FTP网络编程.docx

1、Qt的FTP网络编程利用Qt进行FTP网络编程Qt是一个用于桌面系统和嵌入式开发的跨平台应用程序框架。它包括一个直观的API和一个丰富的类库,并且对通用网络协议提供了很好的支持。在本文中,我们将向读者介绍如何利用Qt提供的网络编程有关的类来进行快速的FTP编程,下面首先介绍FTP协议的基础知识,然后用实例讲解FTP的客户端编程。 一、FTP我们都知道,FTP协议是互联网上的文件传输协议,利用它我们可以将一个文件的副本从一台计算机传输到另一台计算机上。就像许多其他网络应用一样,FTP使用客户/服务器模式。FTP客户打开一个控制连接与服务器连接,通过该连接,客户发送请求并接收应答。控制连接在整个会

2、话期间一直保持开放。FTP并不通过控制连接来发送数据,而是当客户请求文件传输时,服务器形成一个独立的数据连接。由于FTP使用两个不同的协议端口号,所以数据连接与控制连接不会发生混乱。在进行文件传输时,用户运行一个本地FTP应用程序,该程序将解释用户输入的命令。当用户输入open命令并指定一个远程计算机时,本地计算机变成一个使用TCP与指定计算机上的FTP服务器程序建立控制连接的FTP客户。客户与服务器在通过控制连接进行通信时使用FTP协议。也就是说,客户并不直接将用户的键击传递给服务器方。相反,当用户输入命令时,客户首先解释该命令。如果命令要求与服务器交互,那么客户形成一个使用FTP协议的请求

3、,并将请求送到服务器方。服务器在应答时也使用FTP协议。 二、Qt为FTP提供的类实际上,为了方便网络编程,Qt已经提供了许多有关的类,比如QFtp就使我们能够更加轻松使用FTP协议进行网络编程。此外,Qt还用两个低级的类QTcpSocket和QudpSocket,它们实现了TCP和UDP传输协议。我们知道,TCP是一种可靠的面向连接的协议,它用来在两个网络节点之间传输数据流;UDP则是一种不可靠的无连接协议,它用于在网络节点之间发送非连续的数据包。两者都可以用来建立网络客户/服务器模式的应用程序,对于服务器,还需要QTcpServer类来处理进入的TCP连接。如果不用QTcpSocket,而

4、使用QSslSocket的话,还可以建立安全的SSL/TLS连接。好了,有了以上基础知识后,我们从下面开始用示例讲解FTP的客户端编程。三、FTP客户端编程在Qt中,QFtp类为我们实现了FTP协议的客户端所需要的功能,比如它不仅提供了完成最常用的各种FTP操作的函数,还能执行任意的FTP命令。需要注意,QFtp类以异步方式工作,比如当我们调用诸如get()或者put()函数时,会立即返回,当控制权返还给Qt的事件循环后,方才进行数据传输。这样做的好处是,当FTP命令执行过程中,用户界面仍能对客户的动作作出迅速的响应。现在,我们将用实例来说明如何利用get()来检索一个文件。我们的示例是一个控

5、制台程序,名为myftpget,用于下载命令行指定的远程文件。下面让我们首先来看一下该程序的main()函数:intmain(intargc,char*argv)QCoreApplicationapp(argc,argv);QStringListargs=QCoreApplication:arguments();if(args.count()!=2)std:cerrUsage:myftpgeturlstd:endlExample:std:endlmyftpgetftp:/std:endl;return1;MyFtpGetgetter;if(!getter.getFile(QUrl(args1)

6、return1;QObject:connect(&getter,SIGNAL(done(),&app,SLOT(quit();returnapp.exec();我们看到,这里使用的是QCoreApplication,而不是QApplication,这样做是为了防止在编译时连接QtGui程序库。另外,函数QCoreApplication:arguments()返回的命令行参数用作QStringList,其第一项是被调用的程序的名称,这里的任何Qt参数,比如-style 等,都将被删除。Main()函数的重点在于建立MyFtpGet对象并调用getFile(),如果调用成功,就进入事件循环,直到下

7、载结束为止。我们看到,所有的活都是由MyFtpGet子类来干的,其定义如下: classMyFtpGet:publicQObjectQ_OBJECTpublic:MyFtpGet(QObject*parent=0);boolgetFile(constQUrl&url);signals:voiddone();privateslots:voidftpDone(boolerror);private:QFtpftp;QFilefile;这个类具有一个公共函数getFile(),用来检索URL指定的文件。类QUrl提供了一个高级接口,用来提取URL的各个部分,如文件名、路径、协议和端口等等。MyFtpG

8、et具有一个私有的槽,即ftpDone(),当我们的文件传输完成时,就会调用该函数;另外,MyFtpGet还有一个信号,即done(),当文件下载后就会发出该信号。除此之外,这个类还有两个私有变量,分别是变量ftp和变量file。前者类型为QFtp,用来封装至FTP服务器的连接;后者用来将下载的文件写入硬盘。 MyFtpGet:MyFtpGet(QObject*parent):QObject(parent)connect(&ftp,SIGNAL(done(bool),this,SLOT(ftpDone(bool);在构造函数中,我们将信号QFtp:done(bool)连到了私有的槽ftpDon

9、e(bool)上,当处理完所有请求后,QFtp就会发出信号done(bool)。参数bool的作用是指示有没有出错。现在让我们看看getFile()函数:boolMyFtpGet:getFile(constQUrl&url)if(!url.isValid()std:cerrError:InvalidURLstd:endl;returnfalse;if(url.scheme()!=ftp)std:cerrError:URLmuststartwithftp:std:endl;returnfalse;if(url.path().isEmpty()std:cerrError:URLhasnopaths

10、td:endl;returnfalse;QStringlocalFileName=QFileInfo(url.path().fileName();if(localFileName.isEmpty()localFileName=myftpget.out;file.setFileName(localFileName);if(!file.open(QIODevice:WriteOnly)std:cerrError:CannotwritefileqPrintable(file.fileName():qPrintable(file.errorString()std:endl;returnfalse;ft

11、p.connectToHost(url.host(),url.port(21);ftp.login();ftp.get(url.path(),&file);ftp.close();returntrue;GetFile()函数首先检查传递给它的URL,如果有问题,它会向cerr打印错误信息,并返回false,指示下载失败。注意,在这里,我们没有要求用户建立一个文件名,相反,我们设法利用URL本身来生成一个文件名。如果文件打开失败,会打印错误信息并返回false。 接下来,我们使用QFtp对象执行一个由四条FTP命令组成的命令序列。调用url.port(21)后,将返回URL中指定的端口号,如果U

12、RL中没有指定端口号的话,将返回端口21。此外,因为没有向函数login()提供用户名或者口令,所以该函数将尝试匿名登录。给get()的第二个参数规定用于输出的I/O设备。在Qt的事件循环中,将对FTP命令进行排队并执行它们。当所有命令执行完毕后,QFtp将发出信号done(bool),前面已经看到,该信号已经在构造函数中连到了ftpDone(bool)上,那就再看看该函数到底做什么:voidMyFtpGet:ftpDone(boolerror)if(error)std:cerrError:qPrintable(ftp.errorString()std:endl;elsestd:cerrFil

13、edownloadedasqPrintable(file.fileName()std:endl;file.close();emitdone();FTP命令执行后,我们马上关闭该文件,并发出我们自己done()信号。你也许觉得奇怪,为什么会在这里关闭文件呢?好像应该在getFile()函数末尾调用ftp.close()后关闭才对呀?别忘了,FTP命令是异步执行的,也许它们在执行时函数getFile()早就已经返回了。只有当QFtp对象的done()信号发出后,我们才能确切的知道下载已经结束,这时关闭文件才是安全的。 QFtp提供了许多FTP命令,它们是connectToHost()、login(

14、)、close()、list()、cd()、get()、put()、remove()、mkdir()、rmdir()和rename()。这些函数都会发出一个FTP命令,并返回一个标识该命令的ID号。此外,还可以控制传输模式,默认为被动模式,以及传输类型,默认时为二进制类型。另外,所有FTP命令都可以通过rawCommand()来执行,举例来说,可以像下面这样执行SITE CHMOD命令:ftp.rawCommand(SITE CHMOD 755 fortune);当QFtp执行一个命令时,它会发出commandStarted(int)信号;当命令执行完成后,它会发出commandFinishe

15、d(int,bool)信号,其中参数int表示该命令的ID号。如果想了解某个命令的执行情况,可以在调度该命令时记下其ID号,然后通过跟踪ID号就能了解相关情况。举例来说:boolMyFtpGet:getFile(constQUrl&url).connectId=ftp.connectToHost(url.host(),url.port(21);loginId=ftp.login();getId=ftp.get(url.path(),&file);closeId=ftp.close();returntrue;voidMyFtpGet:ftpCommandStarted(intid)if(id=c

16、onnectId)std:cerrConnecting.std:endl;elseif(id=loginId)std:cerrLoggingin.std:endl;.除此之外,还有一种方法可以了解命令执行情况,那就是与QFtp的stateChanged()信号相连接,因为每当该连接进入一个新的状态时(QFtp:Connecting、QFtp:Connected、QFtp:LoggedIn等等),QFtp总会发出相应的stateChanged()信号。 不过在大部分情况下,我们只对命令序列的整体情况感兴趣,而不是单独的某条命令,这时就可以直接与done(bool)信号连接,因为命令队列为空时,就

17、会发出该信号。当遇到错误时,QFtp会自动清空命令队列,也就是说如果连接或者注册失败的话,队列后面的命令就没有机会执行了。如果我们在出错之后使用同一个QFtp对象重新发出命令的话,这些命令将被重新排队并执行。在本程序的.pro文件中,需要用下列行来连接QtNetwork库:QT += network现在,我们将考察一个更加复杂的例子:命令行程序yourftpget,它将下载一个FTP目录中的所有文件,并递归下载该目录下的所有子目录中的文件。有关代码如下所示:classYourftpget:publicQObjectQ_OBJECTpublic:Yourftpget(QObject*parent

18、=0);boolgetDirectory(constQUrl&url);signals:voiddone();privateslots:voidftpDone(boolerror);voidftpListInfo(constQUrlInfo&urlInfo);private:voidprocessNextDirectory();QFtpftp;QListopenedFiles;QStringcurrentDir;QStringcurrentLocalDir;QStringListpendingDirs;这里的起始目录由QUrl指定,然后使用getdirectory()函数进行设置。 Yourf

19、tpget:Yourftpget(QObject*parent):QObject(parent)connect(&ftp,SIGNAL(done(bool),this,SLOT(ftpDone(bool);connect(&ftp,SIGNAL(listInfo(constQUrlInfo&),this,SLOT(ftpListInfo(constQUrlInfo&);在构造函数中,我们建立了两个信号槽连接。当为每个检索的文件请求目录清单时,QFtp就会发出listInfo(const QUrlInfo)信号。这个信号连接到一个称为ftplistinfo()的槽上,该函数会下载给定URL相关联

20、的文件。 boolYourftpget:getDirectory(constQUrl&url)if(!url.isValid()std:cerrError:InvalidURLstd:endl;returnfalse;if(url.scheme()!=ftp)std:cerrError:URLmuststartwithftp:open(QIODevice:WriteOnly)std:cerrWarning:CannotwritefilefileName():errorString()std:endl;return;ftp.get(urlInfo.name(),file);openedFiles

21、.append(file);elseif(urlInfo.isDir()&!urlInfo.isSymLink()pendingDirs.append(currentDir+/+urlInfo.name();槽ftpListInfo()的参数urlInfo提供了远程文件的详细信息,如果该文件是一个常规文件并且可读的话,我们就调用get()来下载之。为此,用new分配一个QFile对象来处理下载,并将指向它的指针放在openedFiles列表中。如果QUrlInfo存放的是远程目录的详细信息,而非一个符号连接的信息,那么就把这个目录添加到pendingDirs列表中。之所以不用符号连接,是因为它

22、常常导致无限递归。 voidYourftpget:ftpDone(boolerror)if(error)std:cerrError:qPrintable(ftp.errorString()std:endl;elsestd:coutDownloadedqPrintable(currentDir)toqPrintable(QDir:toNativeSeparators(QDir(currentLocalDir).canonicalPath();qDeleteAll(openedFiles);openedFiles.clear();processNextDirectory();当全部FTP命令都结束时,或者出现错误时,将会调用槽ftpDone()。为了防止内存泄漏,需要删除QFile对象。最后,我们调用processNextDirectory()。只要还有未处理的目录,就要对列表中的下一个目录进行新一轮的处理;否则,停止下载并发出done()信号。如果没有出现错误的话,FTP命令序列和信号会像下面一样: connectTo

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1