《2015年毕业设计论文BT下载工具的设计和实现毕业论文最终修订版.doc》由会员分享,可在线阅读,更多相关《2015年毕业设计论文BT下载工具的设计和实现毕业论文最终修订版.doc(61页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、哈尔滨工业大学BT下载工具设计与实现摘 要BitTorrent是当今Internet上非常流行的基于P2P技术的内容分发系统,它能够快速、有效地在Internet的网络结点上分发大的文件,而不会给源服务器带来过大负载。BitTorrent协议是一个网络文件传输协议,它能够实现点对点文件分享的技术。BitTorrent协议是用在对等网络中文件分享的网络协议程序,它是用户群对用户群,下载同一文件的人越多,且下载后,继续维持上传的状态,就可以分享,成为其用户端节点下载的种子文件,下载该档案的速度越快。本文的主要工作内容:深入研究了BitTorrent协议及BitTorrent协议的工作原理,QT的信
2、号与槽机制,种子文件的解析过程,客户端和Tracker服务器通信,Peer与Peer之间的通信,DHT网络的实现方法以及BT的关键学法和策略,对软件的系统设计进行论述。 关键字:BitTorrent协议;信号与槽机制;torrent文件解析;哈尔滨工业大学BT download tool design and RealizationAbstractBitTorrent is very popular in todays Internet-based P2P content distribution system technology, it is able to quickly and eff
3、iciently distribute large files over the network nodes of the Internet, rather than the source server will bring excessive load. BitTorrent protocol is a network file transfer protocol that enables peer file sharing technology. BitTorrent protocol is used in peer to peer network file sharing network
4、 protocol procedures, it is the user group for users, download the same file more people, and after downloading, continue to maintain the status of the upload, you can share, as its clients node torrent file, download the file faster. The main content of the paper: in-depth study of the working prin
5、ciple of the BitTorrent protocol and BitTorrent protocol for communication, DHT network QT signals and slots mechanism, the seed file parsing process, the client and server communications Tracker, Peer and Peer between BTs key methods and the study of law and policy, the system design software are d
6、iscussed.Key words:The BitTorrent protocol;Signal and slot mechanism;Torrent file parsing;目 录摘 要IAbstractII1 绪论11.1 国内外BitTorrent的发展状况11.2 发展BitTorrent的目的和意义11.2.1 发展BitTorrent的目的11.2.2 发展BitTorrent的意义12 BitTorrent的原理分析22.1 综述BitTorrent的相关技术22.1.1 BitTorrent协议22.1.2 BitTorrent的专业术语22.1.3 种子的解析32.1.4
7、 BitTorrent运行原理62.1.5 BitTorrent下载流程72.1.6 BitTorrent协议的发展72.2 BitTorrent的软件要求82.2.1 软件系统设计要求82.2.2 软件系统实现83 需求分析103.1 种子文件解析功能分析103.2 Tracker服务器功能分析103.3 Torrent服务器功能分析103.4 软件需求分析104 概要设计114.1.1 种子解析模块114.1.2 连接模块114.1.3 Peer管理模块114.1.4 出错处理模块114.1.5 窗口界面模块115 详细设计135.1 系统功能模块135.2 QT的信号与槽机制145.3
8、BT的算法与策略195.3.1 阻塞算法195.3.2 超级种子算法195.3.3 结束算法205.3.4 防冷落算法205.3.5 最佳无阻塞算法205.3.6 最稀有算法215.4 BT软件的模块的实现215.4.1 种子解析模块的实现21哈尔滨工业大学5.4.2 Client与Traceker通信模块的实现215.4.3 Peer之间的通信模块的实现225.4.4 软件出错模块的实现225.4.5 下载任务状态的实现225.4.6 软件主界面模块的实现225.5 代码实现245.5.1 添加种子代码245.5.2 解析种子代码255.5.3 Peer通信代码275.5.4 窗体中任务代码
9、276 系统测试326.1 测试概述326.2 测试特性326.3 测试种类33结论34参考文献35致谢36外文原文37中文翻译49哈尔滨工业大学1 绪论1.1 国内外BitTorrent的发展状况说到BitTorrent可能有人还不知道是什么东西,但是说到种子可谓是无人不知无人不晓啊!那么在这个下载过程是通过什么支撑的,或者说下载客户端与服务器之间是怎么预定通信的呢,那就是BitTorrent协议,用来进行对种子文件管理和规范。BitTorrent协议是一个网络文件传输协议,它能够实现点对点文件分享的技术。比起其他点对点的协议,它更有多点对多点的特性,这个特点简单的说就是:下载的人越多,速度
10、越快。下载完不马上关闭BitTorrent软件,就可以成为种子即拥有完整的档案者分流让其他人下载,或者说BitTorrent一种分发文件的协议。它通过URL来识别内容,并且可以无缝的和web进行交互。它基于HTTP协议,它的优势是:如果有多个下载者并发的下载同一个文件,那么,每个下载者也同时为其它下载者上传文件,这样,文件源可以支持大量的用户进行下载,而只带来适当的负载的增长。1.2 发展BitTorrent的目的和意义1.2.1 发展BitTorrent的目的 BitTorrent是一种P2P模式,对于P2P模式相对C/S模式,具有很多优点,但是随着P2P应用的不断增多,P2P技术也开始面临
11、一些问题,例如路由效率低下、维护开销过大、系统稳定性差、安全性无法保证以及服务不可靠等问题。因此,在提高现有P2P网络资源定位的效率,降低其维护开销,增强P2P系统的稳定与安全性,提高P2P各个节点提供服务的可靠性等方面都需要做深入的研究。深入研究P2P资源定位技术有重要的理论和现实意义。一方面,随着P2P应用的不断增长,P2P资源定位技术遇到的一系列问题迫切需要我们对它进行更加深入的研究,这将有助于它的进一步推广和使用;另一方面,把P2P资源定位技术与其它的技术相结合,可以达到相互促进的效果,如把P2P资源定位技术引入到通讯领域,把P2P资源定位技术与网格技术相结合,都可以促进彼此的发展。1
12、.2.2 发展BitTorrent的意义发展BitTorrent的意义对于大多数网民是不言而喻的。在平时的生活或学习大多数下载是下载一些音乐,电影和一些软件,尤其是电影,现在是已经进入了高清时代,一部高清电影动辄几个G,在中国的平均网速相对发达国家相对较低的情况下,在以前没有BT技术前,要下载高清电影简直是想都不敢想,占有很高的带宽,文件大,下载时间延长,势必会影响其他工作,而有了BT的迅速发展,通过互联网用户下载这个影片的数量大大加增,下载用户越多,速度越快!甚至有些公司提供离线下载服务,公司通过强大的服务器先通过BitTorrent协议把文件先下载到公司服务器,然后用户再从服务器取回到本地
13、,可靠且速度快。Bitorrent技术广泛应用与电视直播,网络视频和在线游戏中。很多网络游戏的在线更新,比如说如魔兽世界就是采用BT的技术,所以当每次有改版时,动辄数百MB的更新包,通过游戏厂商所提供的更新程序,以BitTorrent协议的方式进行下载分流。这为以往的其他种在线游戏,每次重大改版就必须重新压制光盘,或是等待单一下载点的下载方式,带来另一种节省成本的经营模式。2 BitTorrent的原理分析2.1 综述BitTorrent的相关技术2.1.1 BitTorrent协议对于普通的HTTPFTP下载使用TCP/IP协议,BitTorrent协议是架构于TCP/IP协议之上的一个P2
14、P文件传输协议,处于TCP/IP结构的应用层。 BitTorrent协议本身也包含了很多具体的内容协议和扩展协议,并在不断扩充中。根据BitTorrent协议,文件发布者会根据要发布的文件生成提供一个.torrent文件,即种子文件,也简称为“种子”,可以通过一些种子软件进行种子文件生成。种子文件本质上是文本文件,文本的内容包含Tracker信息和文件信息两部分。Tracker信息主要是BT下载中需要用到的Tracker服务器的地址和针对Tracker服务器的设置,也就是下载软件通过解析种子文件,通过Tracker信息然后和Tracker建立连接,进行通信,从服务器获取到Peer的列表,即你从
15、其他客户端下载文件时建立连接需要的信息,同时也把你的主机的信息上传到Tracker供其他客户端下载。文件信息是根据对目标文件的计算生成的,即根据BitTorrent协议内的Bencode规则进行提供下载文件进行编码。主要是把提供下载的文件虚拟分成大小相等的块,块大小必须为2k的整数次方,由于是虚拟分块,硬盘上并不产生各个块文件,并把每个块的索引信息和Hash验证码写入种子文件中,确保块不被重复下载所以,种子文件就是被下载文件的“索引”。下载时,BT客户端首先解析种子文件得到Tracker地址,然后连接Tracker服务器。Tracker服务器回应下载者的请求,提供下载者其他下载者包括发布者的I
16、P。下载者再连接其他下载者,根据种子文件,两者分别告知对方自己已经有的块,然后交换对方所没有的数据。此时不需要其他服务器参与,分散了单个线路上的数据流量,因此减轻了服务器负担。下载者每得到一个块,需要算出下载块的Hash验证码与种子文件中的对比,如果一样则说明块正确,不一样则需要重新下载这个块。这种规定是为了解决下载内容准确性的问题。一般的HTTP/FTP下载,发布文件仅在某个或某几个服务器,下载的人太多,服务器的带宽很易不胜负荷,变得很慢。而BitTorrent协议下载的特点是,下载的人越多,提供的带宽也越多,下载速度就越快。同时,拥有完整文件的用户也会越来越多,使文件的“寿命”不断延长。为
17、了解决某些用户“下完就跑”的现象,在非官方BitTorrent协议中还存在一种慢慢开放下载内容的超级种子的算法。2.1.2 BitTorrent的专业术语Tracker:收集下载者信息的服务器,并将此信息提供给其他下载者,使下载者们相互连接起来,传输数据。种子:指一个下载任务中所有文件都被某下载者完整的下载,此时下载者成为一个种子。发布者本身发布的文件就是原始种子。也指.torrent文件。做种:发布者提供下载任务的全部内容的行为;下载者下载完成后继续提供给他人下载的行为。2.1.3 种子的解析如图所示为种子文件内容。图2-1 BT种子文件结构图BT种子文件使用了一种叫bencoding的编码
18、方法来保存数据。bencoding现有四种类型的数据:strings(字符串),integers(整数),lists(列表),dictionaries(字典)(1)strings(字符串)编码为:例如:4:test 表示为字符串test,表示长度为4个字节的字符串testStrings类型是没有没开始或结束标记(2)integers(整数)编码为:ie开始标记i,结束标记为e例如:i1234e 表示为整数1234 i-1234e 表示为整数-1234整数没有大小限制(3)lists(列表)编码为:le开始标记为l,结束标记为e列表里可以包含任何bencoding编码类型,包括整数,字符串,列表
19、,字典。例如: l4:test5:abcdee 表示为二个字符串test,abcde(4)dictionaries(字典)编码为de开始标记为d,结束标记为e关键字必须为bencoding字符串值可以为任何bencoding编码类型例如:d3:agei20ee 表示为age=20d4:path3:C:8:filename8:test.txt表示为path=C:,filename=test.txt(5)具体文件结构如下:全部内容必须都为bencoding编码类型。整个文件为一个字典结构,包含如下关键字announce:tracker服务器的URL(字符串)announce-list(可选):备用
20、tracker服务器列表(列表)creation date(可选):种子创建的时间,Unix标准时间comment(可选):备注(字符串)created by(可选):创建人或创建程序的信息(字符串)info:一个字典结构,包含文件的主要信息,分为单文件结构或多文件结构。单文件结构:length:文件长度,单位字节(整数)md5sum(可选):长32个字符的文件的MD5校验(字符串)name:文件名(字符串)piece length:每个块的大小,单位字节(整数)pieces:每个块的20个字节的SHA1 Hash的值(二进制格式)多文件结构如下:files:一个字典结构length:文件长度
21、,单位字节(整数)md5sum(可选):同单文件结构中相同path:文件的路径和名字,是一个列表结构name:最上层的目录名字(字符串)piece length:同单文件结构中相同pieces:同单文件结构中相同综上,多文件Torrent的结构的树形图。图2-2 多文件结构图图2-3 单文件结构图2.1.4 BitTorrent运行原理BT原理普通的HTTP/FTP下载使用TCP/IP协议,BitTorrent协议是架构于TCP/IP协议之上的一个P2P文件传输协议,处于TCP/IP结构的应用层。BitTorrent协议本身也包含了很多具体的内容协议和扩展协议,并在不断扩充中。根据BitTor
22、rent协议,文件发布者会根据要发布的文件生成提供一个.torrent文件,即种子文件,也简称为“种子”。torrent文件本质上是文本文件,包含Tracker信息和文件信息两部分。Tracker信息主要是BT下载中需要用到的Tracker服务器的地址和针对Tracker服务器的设置,文件信息是根据对目标文件的计算生成的,计算结果根据BitTorrent协议内的B编码规则进行编码。它的主要原理是需要把提供下载的文件虚拟分成大小相等的块,块大小必须为2k的整数次方,由于是虚拟分块,硬盘上并不产生各个块文件,并把每个块的索引信息和Hash验证码写入.torrent文件中;所以,种子文件就是被下载文
23、件的“索引”。下载者要下载文件内容,需要先得到相应的.torrent文件,然后使用BT客户端软件进行下载。下载时,BT客户端首先解析.torrent文件得到Tracker地址,然后连接Tracker服务器。Tracker服务器回应下载者的请求,提供下载者其他下载者(包括发布者)的IP。下载者再连接其他下载者,根据.torrent文件,两者分别对方告知自己已经有的块,然后交换对方没有的数据。此时不需要其他扮演服务器参与,分散了单个线路上的数据流量,因此减轻了服务器负担。下载者每得到一个块,需要算出下载块的Hash验证码与.torrent文件中的对比,如果一样则说明块正确,不一样则需要重新下载这个
24、块。这种规定是为了解决下载内容准确性的问题。一般的HTTP/FTP下载,发布文件仅在某个或某几个服务器,下载的人太多,服务器的带宽很易不胜负荷,变得很慢。而BitTorrent协议下载的特点是,下载的人越多,提供的带宽也越多,种子也会越来越多,下载速度就越快。而有些人下载完成后关掉下载任务,提供较少量数据给其他用户,为尽量避免这种行为,在非官方BitTorrent协议中存在超级种子的算法。这种算法允许文件发布者分几步发布文件,发布者不需要一次提供文件所有内容,而是慢慢开放的下载内容的比例,延长下载时间。此时,速度快的人由于未下载完必须提供给他人数据,速度慢的人有更多机会得到数据。2.1.5 B
25、itTorrent下载流程在整个下载过程,tracker服务器一个不可缺少的角色,它不同的下载者之间搭了一个桥梁,下载者在下载开始以及下载进行的过程中,要不停的与tracker服务器进行通信,以汇报自己的信息,并获取其它下载client的信息。这种通信是通过HTTP协议进行的,又被称为tracker HTTP协议,它的过程是这样的:client向tracker发一个HTTP的GET请求,并把它自己的信息放在GET的参数中;这个请求的大致意思是:我是xxx,我想下载yyy文件,我的ip是aaa,我用的端口是bbb。tracker对所有下载者的信息进行维护,当它收到一个请求后,首先把对方的信息记录
26、下来,如果已经记录在案,那么就检查是否需要更新,然后将一部分,并非全部,根据设置的参数已经下载者的请求参与下载同一个文件,一个tracker服务器可能同时维护多个文件的下载,的下载者的信息返回给对方。Client在收到tracker的响应后,就能获取其它下载者的信息,那么它就可以根据这些信息,与其它下载者建立连接,从它们那里下载文件片断。2.1.6 BitTorrent协议的发展最新的DHT网络技术,使得无Tracker下载成为可能。DHT(Distributed Hash Table,分布式哈希表)类似Tracker的根据种子特征码返回种子信息的网络。DHT全称叫分布式哈希表(Distrib
27、uted Hash Table),是一种分布式存储方法。在不需要服务器的情况下,每个客户端负责一个小范围的路由,并负责存储一小部分数据,从而实现整个DHT网络的寻址和存储。新版BitComet允许同行连接DHT网络和Tracker,也就是说在完全不连上Tracker服务器的情况下,也可以很好的下载,因为它可以在DHT网络中寻找下载同一文件的其他用户。有些软件(比特精灵)还会自动通过DHT搜索种子资源,构成种子市场。这种技术好处十分明显,就是大大减轻了Tracker的负担。用户之间可以更快速建立通讯。对越每一个连入DHT网络的计算机就称为一个网络节点,每一个节点,都会得到一个独一无二的ID,相当
28、于DHT网络的身份表示,当然这个ID的计算方法有很多种方法,所以就有各种各样的DHT的实现方式,其中最自然的一种方法就是用他公网上的IP来做ID的计算原形,因为每个主机的IP地址这是独一无二的也是个唯一标示,当然一个计算机也可能有多个网卡,在DHT网络中每一个节点保存了带下载的一部分的资源那么,整个DHT的网络就是一个大的容器,里面存放了一定的资料,即整个DHT网络保存着待下载软件的所有内容,对于网络中的节点资源是共享的,但由于数据在各个节点上是分散的,每个节点上的资源还会变化,所以问题来了,如何找到特定的资源存在于某个节点上,好去索取。在此之前,曾经有许多的方法,来解决这个,问题比如最早的n
29、apster,就是一个巨大的集中式索引服务器,里面存放了所有的资源的位置,这是一个很直观的解决方案,通过索引来查找资源,但是简单的方法虽然有效,也很脆弱,比如他的服务器万一挂掉了,整个napster网络就完蛋了,而且,所有的资源在一起,整个服务器的负担随着资源的增多而越来越多,最后臃肿不堪,所以后来就出现了另一种解决方案,叫做全分布式非结构化网络,走了另一个极端,完全不要中心服务器,每一个节点维护一个邻居列表,类似路由器中路由表,告诉你下载的资源到哪去找,这样如果要找一个东西就问邻居,邻居再问邻居,只要有,总有一天被问到答案,这就是泛洪式搜索,的确在网络路由上掀起了一片数据洪水,最有名的就是G
30、nutella协议,当初我在分析shareaza的时候就遇到这个协议了,当时一头雾水,现在看来这个协议还被做为bt协议的一个补充在被使用着.还有一种解决方案就是综合上述两者的优点,设置一些超级节点,这些节点就好象napster上的中心服务器,里面存放了大量的索引信息,这就叫做半分布式结构,现在流行的bt就是这种技术,混血的就是强大。我这里讲的DHT却是一个完全分布式结构化拓扑网络,是一个完全不需要中心服务器的网络拓扑,然而比非结构化的要有更好的搜索机制,不用泛洪,目前没有BT应用的那么广,不过大家应该注意到了BT和电骡都先后加入了DHT网络,说明这个网络还是很有潜力的,作为BT或者电骡协议的一
31、种补充手段,让你下载的时候,能够找到更多的源,提升了性能,而且完全不需要中心服务器,也是他的一个优点,这个网络有这样的功能,因为他是凝聚了一定的智慧的,不是象上面的那些都是很直观的解决方案,所以他们都不够强大DHT利用了一个小聪明,把节点的id给利用了起来,简单的说,就是把要找的资源,通过hash算法得到一个规范的key,把这个key和资源合在一起,就是一个信息,把这个信息放在和key一样或者距离最近的那个id节点上,这样你知道自己要找什么,用hash算法得到key,然后就在DHT网络里发布搜索信息,指明要和key一样的id的节点,由于每一个节点都维护了一个其他节点的表,所以很快就能找到所要的
32、东西,研究表明,找到所花费的寻址路径长度和每个节点所保存的邻居节点的个数有渐进曲线关系,所以只要说到这一层DHT的奥秘就一目了然了。2.2 BitTorrent的软件要求2.2.1 软件系统设计要求设计一款功能齐备的BitTorrent下载软件,具体要求如下:(1)能够实现对.torrent文件的解析并且显示出来(2)实现对任务的添加,开始,暂停,删除(3)实现多任务多线程下载(4)实现对种子文件的管理2.2.2 软件系统实现软件开发方法:采用面向对象技术开发方法开发语言:C+开发集成环境:QT Creator使用c+作为开发语言,QT作为IDE,对BitTorrent下载过程进行抽象出具体的
33、类。比如任务,种子,tracker等等。3 需求分析3.1 种子文件解析功能分析3.2 Tracker服务器功能分析tracker服务器是BT下载中必须的角色。一个BT client 在下载开始以及下载进行的过程中,要不停的与 tracker 服务器进行通信,以报告自己的信息,并获取其它下载client的信息。这种通信是通过 HTTP 协议进行的,又被称为 tracker HTTP 协议,它的过程是这样的: client 向 tracker 发一个HTTP 的GET请求,并把它自己的信息放在GET的参数中;这个请求的大致意思是:我是xxx,我想下载yyy文件,我的ip是aaa,我用的端口是bb
34、b。 tracker 对所有下载者的信息进行维护,当它收到一个请求后,首先把对方的信息记录下来(如果已经记录在案,那么就检查是否需要更新),然后将一部分(并非全部,根据设置的参数已经下载者的请求)参与下载同一个文件(一个tracker服务器可能同时维护多个文件的下载)的下载者的信息返回给对方。 Client在收到tracker的响应后,就能获取其它下载者的信息,那么它就可以根据这些信息,与其它下载者建立连接,从它们那里下载文件片断。3.3 Torrent服务器功能分析torrent服务器是也是BT下载中必须的角色。Torrent服务器也就一个peer服务器,当peer服务器从tracker服务
35、器拿到peer列表名单的时候,开始和其他peer服务器创建连接,并且不断和彼此进行通信和交换。它的过程是这样的: torrent服务器向另一个torrent服务器发送消息,这个消息的大致意思是:我是xxx,我已经下载过yyy文件或片段,你可以从我这里直接下载。然后另一个torrent服务器也向发送消息,大致意思是:我这里也有下载一些片段,你看看哪些片段你没下载过,你可以下载。3.4 软件需求分析通过可行性研究报告通过不同的角度判断软件的开发可行性,在确定软件开发可行的情况下,我们需要对软件需要实现的各个功能进行详细分析。对于软件开发周期中,需求分析阶段是一个很重要的阶段,因为连需求不明确,怎么
36、才能开发出符合客户需求的软件,在这一阶段做得好,将为整个软件开发项目的成功打下良好的基础。我们必须明确我们要做什么。我们要实现这几个模块:种子的解析,连接模块,Peer管理,出错管理,任务界面管理。4 概要设计4.1.1 种子解析模块1 对种子文件进行解析,获得Traceker服务器的地址,待下载文件的文件名和长度,piece长度和各个piece的hash值。2 实现对种子文件中下载多个文件的解析。4.1.2 连接模块1 连接Traceker,根据HTTP协议构造获取Peer地址的请求,与Traceker建立连接,解析Traceker的响应信息,从而获取各个peer的ip地址和端口号。4.1.
37、3 Peer管理模块1 对下载下来的数据进行hash校验,判断是否已经下载过该piece。2 根据peer的IP地址和端口号连接peer,从peer处下载数据并且将已经下载的数据上传给其他用户。4.1.4 出错处理模块1 出错处理,在软件使用的过程中可能出现各种意想不到大错误,所有要定义整个系统可能出现的错误类型,并且对错误进行相应的提示或捕获处理。4.1.5 窗口界面模块1 本软件的窗口包括一个带有菜单栏,工具栏和状态栏的主窗口,主窗口又分为任务树和任务列表两个视图。用户可以通过任务树或者任务表对结点进行添加,删除等操作,也可以对任务进行分类,实现对资源的管理。 图4-1 任务树图图4-2
38、任务表图5 详细设计5.1 系统功能模块本软件的模块大致如下。客户端主要包括:种子解析,连接管理,片段管理,出错管理,窗口管理。Peer之间peer通信主要是通过tracker服务器来确定和谁通信,而tracker服务对peer的下载信息进行维护。图5-1 系统功能图图5-2 BitTorrent工作原理5.2 QT的信号与槽机制QT 是一个跨平台的 C+ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象、易于扩展、真正的组件编程等特点,更为引人注目的是目前 Linux 上最为流行的 KDE 桌面环境就是建立在 QT 库的基础之上。QT 支持下列平台:MS/WINDOWS-95、98、
39、NT 和 2000;UNIX/X11-Linux、Sun Solaris、HP-UX、Digital Unix、IBM AIX、SGI IRIX;EMBEDDED- 支持 framebuffer 的 Linux 平台。伴随着 KDE 的快速发展和普及,QT 很可能成为 Linux 窗口平台上进行软件开发时的 GUI 首选。信号和槽机制是 QT 的核心机制,要精通 QT 编程就必须对信号和槽有所了解。信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性,也是 QT 区别于其它工具包的重要地方。信号和槽是 QT 自行定义的一种通信机制,它独立于标准的 C/C+ 语言,因此要正确的处
40、理信号和槽,必须借助一个称为 moc(Meta Object Compiler)的 QT 工具,该工具是一个 C+ 预处理程序,它为高层次的事件处理自动生成所需要的附加代码。在我们所熟知的很多 GUI 工具包中,窗口小部件 (widget) 都有一个回调函数用于响应它们能触发的每个动作,这个回调函数通常是一个指向某个函数的指针。但是,在 QT 中信号和槽取代了这些凌乱的函数指针,使得我们编写这些通信程序更为简洁明了。 信号和槽能携带任意数量和任意类型的参数,他们是类型完全安全的,不会像回调函数那样产生 core dumps。所有从 QObject 或其子类 ( 例如 Qwidget) 派生的类
41、都能够包含信号和槽。当对象改变其状态时,信号就由该对象发射 (emit) 出去,这就是对象所要做的全部事情,它不知道另一端是谁在接收这个信号。这就是真正的信息封装,它确保对象被当作一个真正的软件组件来使用。槽用于接收信号,但它们是普通的对象成员函数。一个槽并不知道是否有任何信号与自己相连接。而且,对象并不了解具体的通信机制。你可以将很多信号与单个的槽进行连接,也可以将单个的信号与很多的槽进行连接,甚至于将一个信号与另外一个信号相连接也是可能的,这时无论第一个信号什么时候发射系统都将立刻发射第二个信号。总之,信号与槽构造了一个强大的部件编程机制。信号与槽的定义槽:用来接收信号,可以被看作是普通成
42、员函数,可以被直接调用。支持public,protected,private修饰,用来定义可以调用连接到此槽的范围。public slots:void testslot(const QString& strSeqId); 信号:只需要声明信号名与参数列表即可,像是一个只有声明没有实现的成员函数。 Signals:void testsignal(const QString&); QT会在moc的cpp文件中实现它。下面代码中调用activate的第三个参数是类中信号的序列号。void CTestObject: testsignal (const QString & _t1)void *_a =
43、0, const_cast(reinterpret_cast(&_t1) ;QMetaObject:activate(this, &staticMetaObject, 0, _a); 信号槽的连接与触发通过调用connect()函数建立连接,会把连接信息保存在sender对象中;调用desconnect()函数来取消。connect函数的最后一个参数来用指定连接类型。static bool connect(const QObject *sender, const QMetaMethod &signal,const QObject *receiver, const QMetaMethod &me
44、thod, Qt:ConnectionType type = Qt:AutoConnection); 一切就绪,发射!在sender对象中调用:emit testsignal(“test”); # define emit 上面代码可以看到emit被定义为空,这样在发射信号时就相当于直接调用QT为我们moc出来的函数testsignal(constQString & _t1)。具体的操作由QMetaObject:activate()来处理:遍历所有receiver并触发它们的slots。针对不同的连接类型,这里的派发逻辑会有不同。不同的连接类型剖析QueuedConnection:向receiv
45、er所在线程的消息循环发送事件,此事件得到处理时会调用slot,像Win32的:PostMessage。BlockingQueuedConnection:处理方式和QueuedConnection相同,但发送信号的线程会等待信号处理结束再继续,像Win32的:SendMessage。DirectConnection:在当前线程直接调用receiver的slot,这种类型无法支持跨线程的通信。AutoConnection:当前线程与receiver线程相同时,直接调用slot,否则同QueuedConnection类型。 QObject * const receiver = c-receiver
46、; / determine if this connection should be sent immediately or / put into the event queue if (c-connectionType = Qt:AutoConnection & !receiverInSameThread) | (c-connectionType = Qt:QueuedConnection) queued_activate(sender, signal_absolute_index, c, argv ? argv : empty_argv); continue; #ifndef QT_NO_THREAD . else if (c-connectionType = Qt:BlockingQueuedConnection) locker.unlock(); if (receiverInSameThread) qWarning(Qt: Dead lock detected while activating a BlockingQueuedConnection: Sender is %s(%p), receiver is %s(%p), sender-metaObj