BT下載工具的設(shè)計和實現(xiàn)畢業(yè)論文最終修訂版_第1頁
BT下載工具的設(shè)計和實現(xiàn)畢業(yè)論文最終修訂版_第2頁
BT下載工具的設(shè)計和實現(xiàn)畢業(yè)論文最終修訂版_第3頁
BT下載工具的設(shè)計和實現(xiàn)畢業(yè)論文最終修訂版_第4頁
BT下載工具的設(shè)計和實現(xiàn)畢業(yè)論文最終修訂版_第5頁
已閱讀5頁,還剩57頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

上海復(fù)旦大學(xué)畢業(yè)設(shè)計(論文)用紙緒論國內(nèi)外BitTorrent的發(fā)展?fàn)顩r說到BitTorrent可能有人還不知道是什么東西,但是說到種子可謂是無人不知無人不曉?。∧敲丛谶@個下載過程是通過什么支撐的,或者說下載客戶端與服務(wù)器之間是怎么預(yù)定通信的呢,那就是BitTorrent協(xié)議,用來進(jìn)行對種子文件管理和規(guī)范。BitTorrent協(xié)議是一個網(wǎng)絡(luò)文件傳輸協(xié)議,它能夠?qū)崿F(xiàn)點對點文件分享的技術(shù)。比起其他點對點的協(xié)議,它更有多點對多點的特性,這個特點簡單的說就是:下載的人越多,速度越快。下載完不馬上關(guān)閉BitTorrent軟件,就可以成為種子即擁有完整的檔案者分流讓其他人下載,或者說BitTorrent一種分發(fā)文件的協(xié)議。它通過URL來識別內(nèi)容,并且可以無縫的和web進(jìn)行交互。它基于HTTP協(xié)議,它的優(yōu)勢是:如果有多個下載者并發(fā)的下載同一個文件,那么,每個下載者也同時為其它下載者上傳文件,這樣,文件源可以支持大量的用戶進(jìn)行下載,而只帶來適當(dāng)?shù)呢?fù)載的增長。發(fā)展BitTorrent的目的和意義發(fā)展BitTorrent的目的BitTorrent是一種P2P模式,對于P2P模式相對C/S模式,具有很多優(yōu)點,但是隨著P2P應(yīng)用的不斷增多,P2P技術(shù)也開始面臨一些問題,例如路由效率低下、維護開銷過大、系統(tǒng)穩(wěn)定性差、安全性無法保證以及服務(wù)不可靠等問題。因此,在提高現(xiàn)有P2P網(wǎng)絡(luò)資源定位的效率,降低其維護開銷,增強P2P系統(tǒng)的穩(wěn)定與安全性,提高P2P各個節(jié)點提供服務(wù)的可靠性等方面都需要做深入的研究。深入研究P2P資源定位技術(shù)有重要的理論和現(xiàn)實意義。一方面,隨著P2P應(yīng)用的不斷增長,P2P資源定位技術(shù)遇到的一系列問題迫切需要我們對它進(jìn)行更加深入的研究,這將有助于它的進(jìn)一步推廣和使用;另一方面,把P2P資源定位技術(shù)與其它的技術(shù)相結(jié)合,可以達(dá)到相互促進(jìn)的效果,如把P2P資源定位技術(shù)引入到通訊領(lǐng)域,把P2P資源定位技術(shù)與網(wǎng)格技術(shù)相結(jié)合,都可以促進(jìn)彼此的發(fā)展。發(fā)展BitTorrent的意義發(fā)展BitTorrent的意義對于大多數(shù)網(wǎng)民是不言而喻的。在平時的生活或?qū)W習(xí)大多數(shù)下載是下載一些音樂,電影和一些軟件,尤其是電影,現(xiàn)在是已經(jīng)進(jìn)入了高清時代,一部高清電影動輒幾個G,在中國的平均網(wǎng)速相對發(fā)達(dá)國家相對較低的情況下,在以前沒有BT技術(shù)前,要下載高清電影簡直是想都不敢想,占有很高的帶寬,文件大,下載時間延長,勢必會影響其他工作,而有了BT的迅速發(fā)展,通過互聯(lián)網(wǎng)用戶下載這個影片的數(shù)量大大加增,下載用戶越多,速度越快!甚至有些公司提供離線下載服務(wù),公司通過強大的服務(wù)器先通過BitTorrent協(xié)議把文件先下載到公司服務(wù)器,然后用戶再從服務(wù)器取回到本地,可靠且速度快。Bitorrent技術(shù)廣泛應(yīng)用與電視直播,網(wǎng)絡(luò)視頻和在線游戲中。很多網(wǎng)絡(luò)游戲的在線更新,比如說如魔獸世界就是采用BT的技術(shù),所以當(dāng)每次有改版時,動輒數(shù)百MB的更新包,通過游戲廠商所提供的更新程序,以BitTorrent協(xié)議的方式進(jìn)行下載分流。這為以往的其他種在線游戲,每次重大改版就必須重新壓制光盤,或是等待單一下載點的下載方式,帶來另一種節(jié)省成本的經(jīng)營模式。BitTorrent的原理分析綜述BitTorrent的相關(guān)技術(shù)BitTorrent協(xié)議對于普通的HTTP/FTP下載使用TCP/IP協(xié)議,BitTorrent協(xié)議是架構(gòu)于TCP/IP協(xié)議之上的一個P2P文件傳輸協(xié)議,處于TCP/IP結(jié)構(gòu)的應(yīng)用層。BitTorrent協(xié)議本身也包含了很多具體的內(nèi)容協(xié)議和擴展協(xié)議,并在不斷擴充中。根據(jù)BitTorrent協(xié)議,文件發(fā)布者會根據(jù)要發(fā)布的文件生成提供一個.torrent文件,即種子文件,也簡稱為“種子”,可以通過一些種子軟件進(jìn)行種子文件生成。種子文件本質(zhì)上是文本文件,文本的內(nèi)容包含Tracker信息和文件信息兩部分。Tracker信息主要是BT下載中需要用到的Tracker服務(wù)器的地址和針對Tracker服務(wù)器的設(shè)置,也就是下載軟件通過解析種子文件,通過Tracker信息然后和Tracker建立連接,進(jìn)行通信,從服務(wù)器獲取到Peer的列表,即你從其他客戶端下載文件時建立連接需要的信息,同時也把你的主機的信息上傳到Tracker供其他客戶端下載。文件信息是根據(jù)對目標(biāo)文件的計算生成的,即根據(jù)BitTorrent協(xié)議內(nèi)的Bencode規(guī)則進(jìn)行提供下載文件進(jìn)行編碼。主要是把提供下載的文件虛擬分成大小相等的塊,塊大小必須為2k的整數(shù)次方,由于是虛擬分塊,硬盤上并不產(chǎn)生各個塊文件,并把每個塊的索引信息和Hash驗證碼寫入種子文件中,確保塊不被重復(fù)下載所以,種子文件就是被下載文件的“索引”。下載時,BT客戶端首先解析種子文件得到Tracker地址,然后連接Tracker服務(wù)器。Tracker服務(wù)器回應(yīng)下載者的請求,提供下載者其他下載者包括發(fā)布者的IP。下載者再連接其他下載者,根據(jù)種子文件,兩者分別告知對方自己已經(jīng)有的塊,然后交換對方所沒有的數(shù)據(jù)。此時不需要其他服務(wù)器參與,分散了單個線路上的數(shù)據(jù)流量,因此減輕了服務(wù)器負(fù)擔(dān)。下載者每得到一個塊,需要算出下載塊的Hash驗證碼與種子文件中的對比,如果一樣則說明塊正確,不一樣則需要重新下載這個塊。這種規(guī)定是為了解決下載內(nèi)容準(zhǔn)確性的問題。一般的HTTP/FTP下載,發(fā)布文件僅在某個或某幾個服務(wù)器,下載的人太多,服務(wù)器的帶寬很易不勝負(fù)荷,變得很慢。而BitTorrent協(xié)議下載的特點是,下載的人越多,提供的帶寬也越多,下載速度就越快。同時,擁有完整文件的用戶也會越來越多,使文件的“壽命”不斷延長。為了解決某些用戶“下完就跑”的現(xiàn)象,在非官方BitTorrent協(xié)議中還存在一種慢慢開放下載內(nèi)容的超級種子的算法。BitTorrent的專業(yè)術(shù)語Tracker:收集下載者信息的服務(wù)器,并將此信息提供給其他下載者,使下載者們相互連接起來,傳輸數(shù)據(jù)。種子:指一個下載任務(wù)中所有文件都被某下載者完整的下載,此時下載者成為一個種子。發(fā)布者本身發(fā)布的文件就是原始種子。也指.torrent文件。做種:發(fā)布者提供下載任務(wù)的全部內(nèi)容的行為;下載者下載完成后繼續(xù)提供給他人下載的行為。種子的解析如圖所示為種子文件內(nèi)容。圖2-1BT種子文件結(jié)構(gòu)圖BT種子文件使用了一種叫bencoding的編碼方法來保存數(shù)據(jù)。bencoding現(xiàn)有四種類型的數(shù)據(jù):strings(字符串),integers(整數(shù)),lists(列表),dictionaries(字典)(1)strings(字符串)編碼為:<字符串長度>:<字符串>例如:4:test表示為字符串"test",表示長度為4個字節(jié)的字符串testStrings類型是沒有沒開始或結(jié)束標(biāo)記(2)integers(整數(shù))編碼為:i<整數(shù)>e開始標(biāo)記i,結(jié)束標(biāo)記為e例如:i1234e表示為整數(shù)1234i-1234e表示為整數(shù)-1234整數(shù)沒有大小限制(3)lists(列表)編碼為:l<bencoding編碼類型>e開始標(biāo)記為l,結(jié)束標(biāo)記為e列表里可以包含任何bencoding編碼類型,包括整數(shù),字符串,列表,字典。例如:l4:test5:abcdee表示為二個字符串["test","abcde"](4)dictionaries(字典)編碼為d<bencoding字符串><bencoding編碼類型>e開始標(biāo)記為d,結(jié)束標(biāo)記為e關(guān)鍵字必須為bencoding字符串值可以為任何bencoding編碼類型例如:d3:agei20ee表示為{"age"=20}d4:path3:C:"8:filename8:test.txt表示為{"path"="C:"","filename"="test.txt"}(5)具體文件結(jié)構(gòu)如下:全部內(nèi)容必須都為bencoding編碼類型。整個文件為一個字典結(jié)構(gòu),包含如下關(guān)鍵字announce:tracker服務(wù)器的URL(字符串)announce-list(可選):備用tracker服務(wù)器列表(列表)creationdate(可選):種子創(chuàng)建的時間,Unix標(biāo)準(zhǔn)時間comment(可選):備注(字符串)createdby(可選):創(chuàng)建人或創(chuàng)建程序的信息(字符串)info:一個字典結(jié)構(gòu),包含文件的主要信息,分為單文件結(jié)構(gòu)或多文件結(jié)構(gòu)。單文件結(jié)構(gòu):length:文件長度,單位字節(jié)(整數(shù))md5sum(可選):長32個字符的文件的MD5校驗(字符串)name:文件名(字符串)piecelength:每個塊的大小,單位字節(jié)(整數(shù))pieces:每個塊的20個字節(jié)的SHA1Hash的值(二進(jìn)制格式)多文件結(jié)構(gòu)如下:files:一個字典結(jié)構(gòu)length:文件長度,單位字節(jié)(整數(shù))md5sum(可選):同單文件結(jié)構(gòu)中相同path:文件的路徑和名字,是一個列表結(jié)構(gòu)name:最上層的目錄名字(字符串)piecelength:同單文件結(jié)構(gòu)中相同pieces:同單文件結(jié)構(gòu)中相同綜上,多文件Torrent的結(jié)構(gòu)的樹形圖。圖2-2多文件結(jié)構(gòu)圖圖2-3單文件結(jié)構(gòu)圖BitTorrent運行原理BT原理普通的HTTP/FTP下載使用TCP/IP協(xié)議,BitTorrent協(xié)議是架構(gòu)于TCP/IP協(xié)議之上的一個P2P文件傳輸協(xié)議,處于TCP/IP結(jié)構(gòu)的應(yīng)用層。BitTorrent協(xié)議本身也包含了很多具體的內(nèi)容協(xié)議和擴展協(xié)議,并在不斷擴充中。

根據(jù)BitTorrent協(xié)議,文件發(fā)布者會根據(jù)要發(fā)布的文件生成提供一個.torrent文件,即種子文件,也簡稱為“種子”。

torrent文件本質(zhì)上是文本文件,包含Tracker信息和文件信息兩部分。Tracker信息主要是BT下載中需要用到的Tracker服務(wù)器的地址和針對Tracker服務(wù)器的設(shè)置,文件信息是根據(jù)對目標(biāo)文件的計算生成的,計算結(jié)果根據(jù)BitTorrent協(xié)議內(nèi)的B編碼規(guī)則進(jìn)行編碼。它的主要原理是需要把提供下載的文件虛擬分成大小相等的塊,塊大小必須為2k的整數(shù)次方,由于是虛擬分塊,硬盤上并不產(chǎn)生各個塊文件,并把每個塊的索引信息和Hash驗證碼寫入.torrent文件中;所以,種子文件就是被下載文件的“索引”。

下載者要下載文件內(nèi)容,需要先得到相應(yīng)的.torrent文件,然后使用BT客戶端軟件進(jìn)行下載。

下載時,BT客戶端首先解析.torrent文件得到Tracker地址,然后連接Tracker服務(wù)器。Tracker服務(wù)器回應(yīng)下載者的請求,提供下載者其他下載者(包括發(fā)布者)的IP。下載者再連接其他下載者,根據(jù).torrent文件,兩者分別對方告知自己已經(jīng)有的塊,然后交換對方?jīng)]有的數(shù)據(jù)。此時不需要其他扮演服務(wù)器參與,分散了單個線路上的數(shù)據(jù)流量,因此減輕了服務(wù)器負(fù)擔(dān)。

下載者每得到一個塊,需要算出下載塊的Hash驗證碼與.torrent文件中的對比,如果一樣則說明塊正確,不一樣則需要重新下載這個塊。這種規(guī)定是為了解決下載內(nèi)容準(zhǔn)確性的問題。

一般的HTTP/FTP下載,發(fā)布文件僅在某個或某幾個服務(wù)器,下載的人太多,服務(wù)器的帶寬很易不勝負(fù)荷,變得很慢。而BitTorrent協(xié)議下載的特點是,下載的人越多,提供的帶寬也越多,種子也會越來越多,下載速度就越快。

而有些人下載完成后關(guān)掉下載任務(wù),提供較少量數(shù)據(jù)給其他用戶,為盡量避免這種行為,在非官方BitTorrent協(xié)議中存在超級種子的算法。這種算法允許文件發(fā)布者分幾步發(fā)布文件,發(fā)布者不需要一次提供文件所有內(nèi)容,而是慢慢開放的下載內(nèi)容的比例,延長下載時間。此時,速度快的人由于未下載完必須提供給他人數(shù)據(jù),速度慢的人有更多機會得到數(shù)據(jù)。BitTorrent下載流程在整個下載過程,tracker服務(wù)器一個不可缺少的角色,它不同的下載者之間搭了一個橋梁,下載者在下載開始以及下載進(jìn)行的過程中,要不停的與tracker服務(wù)器進(jìn)行通信,以匯報自己的信息,并獲取其它下載client的信息。這種通信是通過HTTP協(xié)議進(jìn)行的,又被稱為trackerHTTP協(xié)議,它的過程是這樣的:client向tracker發(fā)一個HTTP的GET請求,并把它自己的信息放在GET的參數(shù)中;這個請求的大致意思是:我是xxx,我想下載yyy文件,我的ip是aaa,我用的端口是bbb。tracker對所有下載者的信息進(jìn)行維護,當(dāng)它收到一個請求后,首先把對方的信息記錄下來,如果已經(jīng)記錄在案,那么就檢查是否需要更新,然后將一部分,并非全部,根據(jù)設(shè)置的參數(shù)已經(jīng)下載者的請求參與下載同一個文件,一個tracker服務(wù)器可能同時維護多個文件的下載,的下載者的信息返回給對方。Client在收到tracker的響應(yīng)后,就能獲取其它下載者的信息,那么它就可以根據(jù)這些信息,與其它下載者建立連接,從它們那里下載文件片斷。BitTorrent協(xié)議的發(fā)展最新的DHT網(wǎng)絡(luò)技術(shù),使得無Tracker下載成為可能。DHT(DistributedHashTable,分布式哈希表)類似Tracker的根據(jù)種子特征碼返回種子信息的網(wǎng)絡(luò)。DHT全稱叫分布式哈希表(DistributedHashTable),是一種分布式存儲方法。在不需要服務(wù)器的情況下,每個客戶端負(fù)責(zé)一個小范圍的路由,并負(fù)責(zé)存儲一小部分?jǐn)?shù)據(jù),從而實現(xiàn)整個DHT網(wǎng)絡(luò)的尋址和存儲。新版BitComet允許同行連接DHT網(wǎng)絡(luò)和Tracker,也就是說在完全不連上Tracker服務(wù)器的情況下,也可以很好的下載,因為它可以在DHT網(wǎng)絡(luò)中尋找下載同一文件的其他用戶。有些軟件(比特精靈)還會自動通過DHT搜索種子資源,構(gòu)成種子市場。這種技術(shù)好處十分明顯,就是大大減輕了Tracker的負(fù)擔(dān)。用戶之間可以更快速建立通訊。對越每一個連入DHT網(wǎng)絡(luò)的計算機就稱為一個網(wǎng)絡(luò)節(jié)點,每一個節(jié)點,都會得到一個獨一無二的ID,相當(dāng)于DHT網(wǎng)絡(luò)的身份表示,當(dāng)然這個ID的計算方法有很多種方法,所以就有各種各樣的DHT的實現(xiàn)方式,其中最自然的一種方法就是用他公網(wǎng)上的IP來做ID的計算原形,因為每個主機的IP地址這是獨一無二的也是個唯一標(biāo)示,當(dāng)然一個計算機也可能有多個網(wǎng)卡,在DHT網(wǎng)絡(luò)中每一個節(jié)點保存了帶下載的一部分的資源那么,整個DHT的網(wǎng)絡(luò)就是一個大的容器,里面存放了一定的資料,即整個DHT網(wǎng)絡(luò)保存著待下載軟件的所有內(nèi)容,對于網(wǎng)絡(luò)中的節(jié)點資源是共享的,但由于數(shù)據(jù)在各個節(jié)點上是分散的,每個節(jié)點上的資源還會變化,所以問題來了,如何找到特定的資源存在于某個節(jié)點上,好去索取。在此之前,曾經(jīng)有許多的方法,來解決這個,問題比如最早的napster,就是一個巨大的集中式索引服務(wù)器,里面存放了所有的資源的位置,這是一個很直觀的解決方案,通過索引來查找資源,但是簡單的方法雖然有效,也很脆弱,比如他的服務(wù)器萬一掛掉了,整個napster網(wǎng)絡(luò)就完蛋了,而且,所有的資源在一起,整個服務(wù)器的負(fù)擔(dān)隨著資源的增多而越來越多,最后臃腫不堪,所以后來就出現(xiàn)了另一種解決方案,叫做全分布式非結(jié)構(gòu)化網(wǎng)絡(luò),走了另一個極端,完全不要中心服務(wù)器,每一個節(jié)點維護一個鄰居列表,類似路由器中路由表,告訴你下載的資源到哪去找,這樣如果要找一個東西就問鄰居,鄰居再問鄰居,只要有,總有一天被問到答案,這就是泛洪式搜索,的確在網(wǎng)絡(luò)路由上掀起了一片數(shù)據(jù)洪水,最有名的就是Gnutella協(xié)議,當(dāng)初我在分析shareaza的時候就遇到這個協(xié)議了,當(dāng)時一頭霧水,現(xiàn)在看來這個協(xié)議還被做為bt協(xié)議的一個補充在被使用著.還有一種解決方案就是綜合上述兩者的優(yōu)點,設(shè)置一些超級節(jié)點,這些節(jié)點就好象napster上的中心服務(wù)器,里面存放了大量的索引信息,這就叫做半分布式結(jié)構(gòu),現(xiàn)在流行的bt就是這種技術(shù),混血的就是強大。我這里講的DHT卻是一個完全分布式結(jié)構(gòu)化拓?fù)渚W(wǎng)絡(luò),是一個完全不需要中心服務(wù)器的網(wǎng)絡(luò)拓?fù)?然而比非結(jié)構(gòu)化的要有更好的搜索機制,不用泛洪,目前沒有BT應(yīng)用的那么廣,不過大家應(yīng)該注意到了BT和電騾都先后加入了DHT網(wǎng)絡(luò),說明這個網(wǎng)絡(luò)還是很有潛力的,作為BT或者電騾協(xié)議的一種補充手段,讓你下載的時候,能夠找到更多的源,提升了性能,而且完全不需要中心服務(wù)器,也是他的一個優(yōu)點,這個網(wǎng)絡(luò)有這樣的功能,因為他是凝聚了一定的智慧的,不是象上面的那些都是很直觀的解決方案,所以他們都不夠強大DHT利用了一個小聰明,把節(jié)點的id給利用了起來,簡單的說,就是把要找的資源,通過hash算法得到一個規(guī)范的key,把這個key和資源合在一起,就是一個信息,把這個信息放在和key一樣或者"距離"最近的那個id節(jié)點上,這樣你知道自己要找什么,用hash算法得到key,然后就在DHT網(wǎng)絡(luò)里發(fā)布搜索信息,指明要和key一樣的id的節(jié)點,由于每一個節(jié)點都維護了一個其他節(jié)點的表,所以很快就能找到所要的東西,研究表明,找到所花費的尋址路徑長度和每個節(jié)點所保存的鄰居節(jié)點的個數(shù)有漸進(jìn)曲線關(guān)系,所以只要說到這一層DHT的奧秘就一目了然了。BitTorrent的軟件要求軟件系統(tǒng)設(shè)計要求設(shè)計一款功能齊備的BitTorrent下載軟件,具體要求如下:(1)能夠?qū)崿F(xiàn)對.torrent文件的解析并且顯示出來(2)實現(xiàn)對任務(wù)的添加,開始,暫停,刪除(3)實現(xiàn)多任務(wù)多線程下載(4)實現(xiàn)對種子文件的管理軟件系統(tǒng)實現(xiàn)軟件開發(fā)方法:采用面向?qū)ο蠹夹g(shù)開發(fā)方法開發(fā)語言:C++開發(fā)集成環(huán)境:QTCreator使用c++作為開發(fā)語言,QT作為IDE,對BitTorrent下載過程進(jìn)行抽象出具體的類。比如任務(wù),種子,tracker等等。需求分析種子文件解析功能分析Tracker服務(wù)器功能分析tracker服務(wù)器是BT下載中必須的角色。一個BTclient在下載開始以及下載進(jìn)行的過程中,要不停的與tracker服務(wù)器進(jìn)行通信,以報告自己的信息,并獲取其它下載client的信息。這種通信是通過HTTP協(xié)議進(jìn)行的,又被稱為trackerHTTP協(xié)議,它的過程是這樣的:

client向tracker發(fā)一個HTTP的GET請求,并把它自己的信息放在GET的參數(shù)中;這個請求的大致意思是:我是xxx,我想下載yyy文件,我的ip是aaa,我用的端口是bbb。

tracker對所有下載者的信息進(jìn)行維護,當(dāng)它收到一個請求后,首先把對方的信息記錄下來(如果已經(jīng)記錄在案,那么就檢查是否需要更新),然后將一部分(并非全部,根據(jù)設(shè)置的參數(shù)已經(jīng)下載者的請求)參與下載同一個文件(一個tracker服務(wù)器可能同時維護多個文件的下載)的下載者的信息返回給對方。

Client在收到tracker的響應(yīng)后,就能獲取其它下載者的信息,那么它就可以根據(jù)這些信息,與其它下載者建立連接,從它們那里下載文件片斷。Torrent服務(wù)器功能分析torrent服務(wù)器是也是BT下載中必須的角色。Torrent服務(wù)器也就一個peer服務(wù)器,當(dāng)peer服務(wù)器從tracker服務(wù)器拿到peer列表名單的時候,開始和其他peer服務(wù)器創(chuàng)建連接,并且不斷和彼此進(jìn)行通信和交換。它的過程是這樣的:

torrent服務(wù)器向另一個torrent服務(wù)器發(fā)送消息,這個消息的大致意思是:我是xxx,我已經(jīng)下載過yyy文件或片段,你可以從我這里直接下載。然后另一個torrent服務(wù)器也向發(fā)送消息,大致意思是:我這里也有下載一些片段,你看看哪些片段你沒下載過,你可以下載。軟件需求分析通過可行性研究報告通過不同的角度判斷軟件的開發(fā)可行性,在確定軟件開發(fā)可行的情況下,我們需要對軟件需要實現(xiàn)的各個功能進(jìn)行詳細(xì)分析。對于軟件開發(fā)周期中,需求分析階段是一個很重要的階段,因為連需求不明確,怎么才能開發(fā)出符合客戶需求的軟件,在這一階段做得好,將為整個軟件開發(fā)項目的成功打下良好的基礎(chǔ)。我們必須明確我們要做什么。我們要實現(xiàn)這幾個模塊:種子的解析,連接模塊,Peer管理,出錯管理,任務(wù)界面管理。概要設(shè)計種子解析模塊對種子文件進(jìn)行解析,獲得Traceker服務(wù)器的地址,待下載文件的文件名和長度,piece長度和各個piece的hash值。實現(xiàn)對種子文件中下載多個文件的解析。連接模塊連接Traceker,根據(jù)HTTP協(xié)議構(gòu)造獲取Peer地址的請求,與Traceker建立連接,解析Traceker的響應(yīng)信息,從而獲取各個peer的ip地址和端口號。Peer管理模塊對下載下來的數(shù)據(jù)進(jìn)行hash校驗,判斷是否已經(jīng)下載過該piece。根據(jù)peer的IP地址和端口號連接peer,從peer處下載數(shù)據(jù)并且將已經(jīng)下載的數(shù)據(jù)上傳給其他用戶。出錯處理模塊出錯處理,在軟件使用的過程中可能出現(xiàn)各種意想不到大錯誤,所有要定義整個系統(tǒng)可能出現(xiàn)的錯誤類型,并且對錯誤進(jìn)行相應(yīng)的提示或捕獲處理。窗口界面模塊本軟件的窗口包括一個帶有菜單欄,工具欄和狀態(tài)欄的主窗口,主窗口又分為任務(wù)樹和任務(wù)列表兩個視圖。用戶可以通過任務(wù)樹或者任務(wù)表對結(jié)點進(jìn)行添加,刪除等操作,也可以對任務(wù)進(jìn)行分類,實現(xiàn)對資源的管理。圖4-1任務(wù)樹圖圖4-2任務(wù)表圖詳細(xì)設(shè)計系統(tǒng)功能模塊本軟件的模塊大致如下。客戶端主要包括:種子解析,連接管理,片段管理,出錯管理,窗口管理。Peer之間peer通信主要是通過tracker服務(wù)器來確定和誰通信,而tracker服務(wù)對peer的下載信息進(jìn)行維護。圖5-1系統(tǒng)功能圖圖5-2BitTorrent工作原理QT的信號與槽機制QT是一個跨平臺的C++GUI應(yīng)用構(gòu)架,它提供了豐富的窗口部件集,具有面向?qū)ο蟆⒁子跀U展、真正的組件編程等特點,更為引人注目的是目前Linux上最為流行的KDE桌面環(huán)境就是建立在QT庫的基礎(chǔ)之上。QT支持下列平臺:MS/WINDOWS-95、98、NT和2000;UNIX/X11-Linux、SunSolaris、HP-UX、DigitalUnix、IBMAIX、SGIIRIX;EMBEDDED-支持framebuffer的Linux平臺。伴隨著KDE的快速發(fā)展和普及,QT很可能成為Linux窗口平臺上進(jìn)行軟件開發(fā)時的GUI首選。信號和槽機制是QT的核心機制,要精通QT編程就必須對信號和槽有所了解。信號和槽是一種高級接口,應(yīng)用于對象之間的通信,它是QT的核心特性,也是QT區(qū)別于其它工具包的重要地方。信號和槽是QT自行定義的一種通信機制,它獨立于標(biāo)準(zhǔn)的C/C++語言,因此要正確的處理信號和槽,必須借助一個稱為moc(MetaObjectCompiler)的QT工具,該工具是一個C++預(yù)處理程序,它為高層次的事件處理自動生成所需要的附加代碼。在我們所熟知的很多GUI工具包中,窗口小部件(widget)都有一個回調(diào)函數(shù)用于響應(yīng)它們能觸發(fā)的每個動作,這個回調(diào)函數(shù)通常是一個指向某個函數(shù)的指針。但是,在QT中信號和槽取代了這些凌亂的函數(shù)指針,使得我們編寫這些通信程序更為簡潔明了。信號和槽能攜帶任意數(shù)量和任意類型的參數(shù),他們是類型完全安全的,不會像回調(diào)函數(shù)那樣產(chǎn)生coredumps。所有從QObject或其子類(例如Qwidget)派生的類都能夠包含信號和槽。當(dāng)對象改變其狀態(tài)時,信號就由該對象發(fā)射(emit)出去,這就是對象所要做的全部事情,它不知道另一端是誰在接收這個信號。這就是真正的信息封裝,它確保對象被當(dāng)作一個真正的軟件組件來使用。槽用于接收信號,但它們是普通的對象成員函數(shù)。一個槽并不知道是否有任何信號與自己相連接。而且,對象并不了解具體的通信機制。你可以將很多信號與單個的槽進(jìn)行連接,也可以將單個的信號與很多的槽進(jìn)行連接,甚至于將一個信號與另外一個信號相連接也是可能的,這時無論第一個信號什么時候發(fā)射系統(tǒng)都將立刻發(fā)射第二個信號??傊?,信號與槽構(gòu)造了一個強大的部件編程機制。信號與槽的定義槽:用來接收信號,可以被看作是普通成員函數(shù),可以被直接調(diào)用。支持public,protected,private修飾,用來定義可以調(diào)用連接到此槽的范圍。publicslots:voidtestslot(constQString&strSeqId);信號:只需要聲明信號名與參數(shù)列表即可,像是一個只有聲明沒有實現(xiàn)的成員函數(shù)。Signals:voidtestsignal(constQString&);QT會在moc的cpp文件中實現(xiàn)它。下面代碼中調(diào)用activate的第三個參數(shù)是類中信號的序列號。voidCTestObject::testsignal(constQString&_t1){void*_a[]={0,const_cast<void*>(reinterpret_cast<constvoid*>(&_t1))};QMetaObject::activate(this,&staticMetaObject,0,_a);}信號槽的連接與觸發(fā)通過調(diào)用connect()函數(shù)建立連接,會把連接信息保存在sender對象中;調(diào)用desconnect()函數(shù)來取消。connect函數(shù)的最后一個參數(shù)來用指定連接類型。staticboolconnect(constQObject*sender,constQMetaMethod&signal,constQObject*receiver,constQMetaMethod&method,Qt::ConnectionTypetype=Qt::AutoConnection);一切就緒,發(fā)射!在sender對象中調(diào)用:emittestsignal(“test”);#defineemit上面代碼可以看到emit被定義為空,這樣在發(fā)射信號時就相當(dāng)于直接調(diào)用QT為我們moc出來的函數(shù)testsignal(constQString&_t1)。具體的操作由QMetaObject::activate()來處理:遍歷所有receiver并觸發(fā)它們的slots。針對不同的連接類型,這里的派發(fā)邏輯會有不同。不同的連接類型剖析QueuedConnection:向receiver所在線程的消息循環(huán)發(fā)送事件,此事件得到處理時會調(diào)用slot,像Win32的::PostMessage。BlockingQueuedConnection:處理方式和QueuedConnection相同,但發(fā)送信號的線程會等待信號處理結(jié)束再繼續(xù),像Win32的::SendMessage。DirectConnection:在當(dāng)前線程直接調(diào)用receiver的slot,這種類型無法支持跨線程的通信。AutoConnection:當(dāng)前線程與receiver線程相同時,直接調(diào)用slot,否則同QueuedConnection類型。QObject*constreceiver=c->receiver;//determineifthisconnectionshouldbesentimmediatelyor//putintotheeventqueueif((c->connectionType==Qt::AutoConnection&&!receiverInSameThread)||(c->connectionType==Qt::QueuedConnection)){queued_activate(sender,signal_absolute_index,c,argv?argv:empty_argv);continue;#ifndefQT_NO_THREAD.}elseif(c->connectionType==Qt::BlockingQueuedConnection){locker.unlock();if(receiverInSameThread){qWarning("Qt:DeadlockdetectedwhileactivatingaBlockingQueuedConnection:""Senderis%s(%p),receiveris%s(%p)",sender->metaObject()->className(),sender,receiver->metaObject()->className(),receiver);}QSemaphoresemaphore;QCoreApplication::postEvent(receiver,newQMetaCallEvent(c->method_offset,c->method_relative,c->callFunction,sender,signal_absolute_index,0,0,argv?argv:empty_argv,&semaphore));semaphore.acquire();locker.relock();continue;#endif}QT對象所屬線程的概念這里要引入QObject的所屬線程概念,看一下QObject的構(gòu)造函數(shù)(隨便選擇一個重載)就一目了然了。如果指定父對象并且父對象的當(dāng)前線程數(shù)據(jù)有效,則繼承,否則把創(chuàng)建QObject的線程作為所屬線程。QObject::QObject(QObject*parent):d_ptr(newQObjectPrivate){Q_D(QObject);d_ptr->q_ptr=this;d->threadData=(parent&&!parent->thread())?parent->d_func()->threadData:QThreadData::current();d->threadData->ref();if(parent){QT_TRY{if(!check_parent_thread(parent,parent?parent->d_func()->threadData:0,d->threadData))parent=0;setParent(parent);}QT_CATCH(...){d->threadData->deref();QT_RETHROW;}}qt_addObject(this);}通過activate()的代碼可以看到,除了信號觸發(fā)線程與接收者線程相同的情況能直接調(diào)用到slot,其它情況都依賴事件機制,也就是說receiver線程必須要有QT的eventloop,否則slot函數(shù)是沒有機會觸發(fā)的!當(dāng)我們奇怪為什么信號發(fā)出slot卻不被觸發(fā)時,可以檢查一下是否涉及到跨線程,接收者的線程是否存在激活的eventloop。所幸,我們可以通過調(diào)用QObject的方法movetothread,來更換對象的所屬線程,將有需求接收信號的對象轉(zhuǎn)移到擁有消息循環(huán)的線程中去以確保slot能正常工作。有一個和對象所屬線程相關(guān)的坑:QObject::deletelater()。從源碼可以看出,這個調(diào)用也只是發(fā)送了一個事件,等對象所屬線程的消息循環(huán)獲取控制權(quán)來處理這個事件時做真正的delete操作。所以調(diào)用這個方法要謹(jǐn)慎,確保對象所屬線程具有激活的eventloop,不然這個對象就被泄露了!voidQObject::deleteLater(){QCoreApplication::postEvent(this,newQEvent(QEvent::DeferredDelete));}強制線程切換當(dāng)對象中的一些接口需要確保在具有消息循環(huán)的線程中才能正確工作時,可以在接口處進(jìn)行線程切換,這樣無論調(diào)用者在什么線程都不會影響對象內(nèi)部的操作。下面的類就是利用信號槽機制來實現(xiàn)線程切換與同步,所有對testMethod()的調(diào)用都會保證執(zhí)行在具有事件循環(huán)的線程中。classCTestObject:publicQObject{Q_OBJECTpublic:CTestObject(QObject*parent=NULL):QObject(parent){//把自己轉(zhuǎn)移到帶有事件循環(huán)的QThreadthis->moveToThread(&m_workThread);//外部調(diào)用一律通過信號槽轉(zhuǎn)移到對象內(nèi)部的工作線程//連接類型選擇為Qt::BlockingQueuedConnection來達(dá)到同步調(diào)用的效果。connect(this,SIGNAL(signalTestMethod(constQString&)),this,SLOT(slotTestMethod(constQString&)),Qt::BlockingQueuedConnection);m_workThread.start();}~CTestObject();voidtestMethod(constQString&strArg){if(QThread::currentThreadId()==this->d_func()->threadData->threadId){//如果調(diào)用已經(jīng)來自對象所屬線程,直接處理slotTestMethod(strArg);}else{//通過發(fā)送信號,實現(xiàn)切換線程處理emitsignalTestMethod(strArg);}}signals:voidsignalTestMethod(constQString&);privateslots:voidslotTestMethod(constQString&strArg){//方法的具體實現(xiàn)}private:QThread m_workThread;};BT的算法與策略阻塞算法BT并不集中分配資源。每個peer自己有責(zé)任來盡可能的提高它的下載速率。Peers從它可以連接的peers處下載文件,并根據(jù)對方提供的下載速率給予同等的上傳回報。對于合作者,提供上傳服務(wù),對于不合作的,就阻塞對方。所以說,阻塞是一種臨時的拒絕上傳策略,雖然上傳停止了,但是下載仍然繼續(xù)。在阻塞停止的時候,連接并不需要重新建立。每個客戶端一直與固定數(shù)量的peer保持疏通,通常情況下是4個,嚴(yán)格地根據(jù)當(dāng)前的下載速度來決定哪些peer應(yīng)該保持疏通,通過計算最近10秒從每個peer處下載數(shù)據(jù)的速度來計算下載速度,如果只是簡單地為提供最高下載速率的4個peer提供上載服務(wù),那么就沒有辦法發(fā)現(xiàn)那些空閑的連接是否有更好的下載速度,為了解決這個問題,在任何時候,每個peer都擁有一個成為optimisticunchoking優(yōu)化非阻塞,這個連接總是疏通狀態(tài),而不管它的下載速率是多少,每隔30秒,重新選擇一個peer作為優(yōu)化非阻塞的peer,一旦某一個peer完成了下載,它不能再通過下載速率來決定哪些peer提供上載了。目前采用的解決辦法是:優(yōu)先選擇那些從它這里得到更好下載速率的peer,保持與它們的疏通,這樣做的理由是盡可能的利用上載帶寬,一旦某一個peer完成下載,那么它也就成為了種子。超級種子算法超級種子概念不是老版本BT協(xié)議的一部分。S5.5中的超級種子的概念是為幫助那些自身帶寬有限(對支持大的Torrent來說)的發(fā)起者而設(shè)計的一種新的做種算法,它能使發(fā)起者減少需要上傳的數(shù)據(jù)量以便spawnnewseedsinthetorrent。當(dāng)一個做種的Client進(jìn)入了超級種子模式,它的行為將不同于普通的做種者,而是扮成一個不擁有任何數(shù)據(jù)的普通Client。當(dāng)其他的Client和它建立連接之后,它將通知這些Clients自己收到了一個從未被發(fā)送過的Piece(所有Piece都被發(fā)送過的情況是很罕見的),這就使得Clients只試圖下載這一個Piece(而沒有其他想法)。當(dāng)Clients下載完這個Piece后,超級種子不再通知他們下載其他的Pieces直到它看到剛剛傳送的那一個Piece已經(jīng)被至少一個其他的Client提供下載。因此在那之前,Clients都不會訪問超級種子的其他Pieces,這樣就節(jié)省了超級種子的帶寬。這種方法將提高做種的效率,既讓Peers去下載最稀有的數(shù)據(jù)(降低了傳送的多余數(shù)據(jù)量),又限制了傳送給Peers的對Swarm沒有任何貢獻(xiàn)的數(shù)據(jù)量。這種算法未出現(xiàn)之前,一個種子在其他Client成為種子之前,可能需要上傳150%~200%于Torrent的數(shù)據(jù)量。而現(xiàn)在,一個運行在超級種子模式下的Client(對一個大的Torrent做種),只需要上傳105%于Torrent的數(shù)據(jù)量。這相當(dāng)于一個普通種子做種效率的150%~200%。但是,在通常情況下不建議使用超級種子模式。雖然它有助于稀有數(shù)據(jù)的分發(fā)(因為它對Client的下載選擇做出了限制,同時也限制了Clients下載已經(jīng)部分得到的數(shù)據(jù)),所以超級種子模式只適用于那些最初做種的Server。結(jié)束算法當(dāng)下載將要結(jié)束時,將會趨向最后的幾個piece-sections下載減慢,為了加速下載,客戶端向所有peers發(fā)送請求下載其沒有的piece。為了保證傳輸過多的冗余數(shù)據(jù)而到是性能下降,客戶端一旦收到piece-sections,向所有的其他peers發(fā)送cancel消息。至于什么時候啟動END

GAME算法。規(guī)范沒有給出推薦值。防冷落算法偶然情況下,BT的peer端可能會被它下載的所有的peers端阻塞。這種情況下,此peer端的下載速率就很低,直到優(yōu)化unchock算法找到更好的peers端。為了消除這個問題,當(dāng)超過一分鐘一個peer沒有從特定的peer得到一個piece那么BT就認(rèn)為它被那個peer冷落。并不上傳給它直到優(yōu)化unchoke(這是對于上述的優(yōu)化unchocke算法的一個例外),這就常常會使多于一個peers同時進(jìn)入優(yōu)化unchoke狀態(tài)。從而使下載速率快速恢復(fù)。最佳無阻塞算法當(dāng)同一時刻通過多個連接發(fā)送數(shù)據(jù)時,TCP擁塞控制的效果很差。這樣,Choking就允許Peers使用一種tit-for-tat-ish算法來確保他們獲得一個穩(wěn)定的下載速率。下面介紹的Choking算法是目前BT客戶端中所廣泛采用的。很重要的一點是,所有新的算法既能用在包含他們?nèi)康木W(wǎng)絡(luò)上,也能用在只包含此算法的網(wǎng)絡(luò)上。好的Choking算法應(yīng)該滿足如下準(zhǔn)則:1.為了獲得好的TCP性能,它應(yīng)限制同時上傳的數(shù)量;2.應(yīng)避免阻塞和非阻塞狀態(tài)的頻繁切換(Fibrillation);3.應(yīng)該酬謝讓自己下載的Peer,為它提供上載;4.當(dāng)發(fā)現(xiàn)更好的連接(相對于當(dāng)前的連接)的時候,試圖啟用他們,稱作Optimistic

Unchoking。

目前使用的Choking算法中避免Fibrillation(抖動)的唯一策略是:每10秒更新被阻塞的Peers。酬謝(Reciprocation)和限制上傳的數(shù)目通過解除(對自己感興趣的且擁有最好的上載速率的)4個Peers的阻塞來管理。這樣可以獲得最大的下載速率。而這四個Peers因?qū)焊信d趣而成為下載者。擁有更好的上載速率(相對于下載者而言)但對自己不感興趣的Peer被阻塞,但一旦當(dāng)它對自己感興趣,則阻塞上載速率最慢的下載者,使其取而代之成為新的下載者。如果一個Client擁有完整的資源文件,則它將根據(jù)上載速率而不是下載速率來決定阻塞哪些Peer。對于Optimistic

Unchoked,在任意時刻都會有一個不被阻塞的Peer而不管它的上載速率如何(如果它對自己感興趣,則成為4個下載者中的一員),至于哪一個Peer被Optimistic

Unchoked,會每30秒更新一次。最新連接的Peer成為Optimistic

Unchoked的可能性是其他Peers的3倍,這將給他們一個很好的機會去完成一個Piece的上載。最稀有算法BT中下載piece策略為,最稀少最優(yōu)先原則。每個peer都優(yōu)先選擇整個系統(tǒng)中最少的那些片斷去下載,而那些在系統(tǒng)中相對較多的片斷,放在后面下載,這樣,整個系統(tǒng)就趨向于一種更優(yōu)的狀態(tài)。如果不用這種算法,大家都去下載最多的那些片斷,那么這些片斷就會在系統(tǒng)中分布的越來越多,而那些在系統(tǒng)中相對較少的片斷仍然很少,最后,某些

peer

就不再擁有其它

peer

感興趣的片斷了,那么系統(tǒng)的參與者越來越少,整個系統(tǒng)的性能就下降。客戶端通過保留每個peer端的原始bitfield域來決定下載在bitfield里面出現(xiàn)頻率最小的piece。程序的具體實現(xiàn)是通過

have

消息來計算。在下載過程中,會不停的收到其它

peer

發(fā)來的

have

消息,每個have消息都表明對方擁有了某個片斷(即某個完整的piece)。那么,為每個片斷維護一個計數(shù)器,每收到一個have消息,相應(yīng)的計數(shù)器加1。在選擇片斷的時候,計數(shù)器最小的某個片斷被選中。

“最少優(yōu)先”的一個例外是在下載剛開始的時候。此時,下載者沒有任何片斷可供上傳,所以,需要盡快的獲取一個完整的片斷。而最少的片斷,通常只有某一個peer擁有,所以,它可能比多個peers都擁有的那些片斷下載的要慢。因此,第一個片斷是隨機選擇的,直到第一個片斷下載完成,才切換到“最少優(yōu)先”的策略。BT軟件的模塊的實現(xiàn)種子解析模塊的實現(xiàn)根據(jù)種子文件的結(jié)構(gòu)信息,我門可以構(gòu)造文件的實體類,種子文件也可以被稱為元信息文件,它是通過B編碼,就是一個B編碼的字典。因為在下載的文件可能是單個文件也有可能是多個文件,所以定義一個單文件結(jié)構(gòu)體MetaInfoSingleFile,包含有長度,md5,名字,還有piece的長度等屬性,然后再定義一個結(jié)構(gòu)體為多文件結(jié)構(gòu)體MetaInfoMultiFile。對于種子文件我們相應(yīng)的定義一個MetaInfo,這個類保存種子的信息。.torrent說白就是個文本文件,對這文本文件讀取保存到一個字節(jié)數(shù)組里面,MetaInfo通過調(diào)用parse(QByteArray)方法對字節(jié)數(shù)組進(jìn)行解析,之后種子的所有信息就保存到一個MetaInfo對象中。Client與Traceker通信模塊的實現(xiàn)解析完種子文件以后,種子的所有信息保存在實體類里面,可以通過類里面的一些方法獲取種子的信息,完成種子的解析后,可以從中獲取到Tracker服務(wù)器的URI后就可以開始和Tracker進(jìn)行交互,在與traceker連接之后,tracker可以對一些自己下載進(jìn)度進(jìn)行統(tǒng)計,并且客戶端可以獲取到當(dāng)前下載同一文件的peer的IP地址和端口號。BitTorrent協(xié)議是在TCP/IP協(xié)議之上的應(yīng)用層協(xié)議,客戶端使用HTTP協(xié)議與Tracker進(jìn)行通信,Tracker通過HttpGET方法獲取請求,然后Tracker服務(wù)器返回信息,返回信息是一個經(jīng)過B編碼的字典,包含著可以下載的peer的IP地址和端口號,和一些peer的長度等信息,然后客戶端可以根據(jù)返回信息進(jìn)行連接下載peer,并且在客戶端下載完成peer以后,把相應(yīng)的信息提交daotracker服務(wù)器,其他客戶端可以根據(jù)Tracker服務(wù)器上面的信息得到你的ip地址和端口號,別人和你建立連接以后就可以下載你已經(jīng)下載好的Peer.在這個軟件開發(fā)過程中抽象出一個類TrackerClient,這個類主要和traceker服務(wù)器進(jìn)行通信,包括請求和獲取。Peer之間的通信模塊的實現(xiàn)Peer之間通信協(xié)議可以稱為peer連線協(xié)議,它是一個基于TCP協(xié)議的應(yīng)用層協(xié)議,為防止有的peer只下載不上傳,BT協(xié)議建議:客戶端只給那些向它提供最快下載速度的4個Peer上傳數(shù)據(jù),簡單地說就是誰向我提供下載,我就提供數(shù)據(jù)供他下載;誰不提供數(shù)據(jù)給我下載,我的數(shù)據(jù)也不會上傳給它。客戶端每隔一定時間,重新計算從各個peer處下載數(shù)據(jù)的速度,將下載速度最快的4個peer解除阻塞,允許這4個peer從客戶端下載數(shù)據(jù),同時將其他peer阻塞。對客戶端與其他peer建立連接之后,既要做服務(wù)器又要做客戶端,所以相應(yīng)的有個作為客戶端的類和作為服務(wù)器的類,一個負(fù)責(zé)從別的peer下載片段并且保存,一個負(fù)責(zé)上傳本地已經(jīng)下載好的片段。軟件出錯模塊的實現(xiàn)在整個軟件系統(tǒng)中定義5中錯誤狀態(tài),并且對這五種錯誤進(jìn)行了相應(yīng)的處理有UnknownError,TorrentParseError,InvalidTrackerError,FileErrorServerError在打開種子文件,和文件解析過程中或通信過程可能出現(xiàn)不同錯誤,要對不同的錯誤進(jìn)行捕獲,并且進(jìn)行處理。下載任務(wù)狀態(tài)的實現(xiàn)對于整個軟件來說,添加一個種子文件,即為創(chuàng)建一個任務(wù),任務(wù)的狀態(tài)分為:Idle,Paused,Stopping,Preparing,Searching,Connecting,WarmingUp,Downloading,EndGame,Seeding.在peer與peer通信過程中或client與traceker服務(wù)器通信過程中會影響任務(wù)的狀態(tài)。軟件主界面模塊的實現(xiàn)主界面效果如圖所示。圖5-3BT軟件下載任務(wù)效果圖圖5-3BT軟件下載任務(wù)效果圖圖5-4BT軟件添加任務(wù)圖圖5-4BT軟件添加任務(wù)圖代碼實現(xiàn)添加種子代碼如圖所示。圖5-5BT軟件添加種子代碼圖圖5-6BT軟件種子添加代碼圖//添加TorrentboolMainWindow::addTorrent(){//選擇torrent文件QStringfileName=QFileDialog::getOpenFileName(this,tr("請選擇一個文件"),lastDirectory,tr("種子文件(*.torrent);;""所有文件(*.*)"));if(fileName.isEmpty())returnfalse;lastDirectory=QFileInfo(fileName).absolutePath();qDebug()<<lastDirectory<<endl;//顯示添加種子文件對話框AddTorrentDialog*addTorrentDialog=newAddTorrentDialog(this);addTorrentDialog->setTorrent(fileName);addTorrentDialog->deleteLater();if(!addTorrentDialog->exec())returnfalse;//添加任務(wù)到列表中需要把種子文件的路徑和保存路徑作為參數(shù)傳過去addTorrent(fileName,addTorrentDialog->getDestinationFolder());if(!saveChanges){saveChanges=true;QTimer::singleShot(1000,this,SLOT(saveSettings()));}returntrue;}解析種子代碼MetaInfoSingleFile是相應(yīng)的單文件結(jié)構(gòu)體MetaInfoMultiFile是相應(yīng)的多文件結(jié)構(gòu)體MetaInfo是相應(yīng)的種子文件的實體類structMetaInfoSingleFile{qint64length;QByteArraymd5sum;QStringname;intpieceLength;QList<QByteArray>sha1Sums;};structMetaInfoMultiFile{qint64length;QByteArraymd5sum;QStringpath;};classMetaInfo{public:enumFileForm{SingleFileForm,MultiFileForm};}這個主要就是用來解析種子文件,轉(zhuǎn)換為MetaInfoboolMetaInfo::parse(constQByteArray&data){//傳過來的就是個文件流,然后文件進(jìn)行bencoding編碼解析即可returntrue;}Peer通信代碼trackerclient.cpp主要是負(fù)責(zé)軟件與Tracker的通信,用來負(fù)責(zé)獲取peer列表和提交自己的進(jìn)度就是用來獲取peer列表voidTrackerClient::fetchPeerList(){從種子文件獲取Tracker的url對本地的片段進(jìn)行hash算法,向服務(wù)提交本地的下載信息發(fā)送Http請求}torrentclient.cpp主要是本機作為客戶端,從其他Peer下載片段本機連接到Peer,從peer獲取數(shù)據(jù)voidTorrentClient::connectToPeers(){//根據(jù)獲取的peer列表的信息,連接主機,建立連接//啟動一個通信線程處理數(shù)據(jù)交換}torrentserver.cpp主要是本機作為服務(wù)端,為其他Peer提供下載這個函數(shù)主要負(fù)責(zé)其他Peer請求連接,然后建立連接voidTorrentServer::incomingConnection(qintptrsocketDescriptor)窗體中任務(wù)代碼如圖所示。圖5-7主窗體代碼圖mytablewidget.cpp主要負(fù)責(zé)對表格視圖中任務(wù)的更刪改查//添加任務(wù)行voidaddTaskRow(QStringname,QStringsize);//刪除選擇任務(wù)行voiddeleteTaskRow(intindex);//刪除選擇所有行voiddeleteAllTaskRow();mytreewidget.cpp主要負(fù)責(zé)對樹視圖中任務(wù)的更刪改查//向樹添加節(jié)點voidaddNodeToTaskNode(QStringfileName);//通過行號刪除樹的節(jié)點voidremoveNodeFromTaskNode(introw);mainwindow.cpp這是個容器用來放表格視圖和樹視圖還有就是一些窗口的初始化和設(shè)置//導(dǎo)入設(shè)置voidloadSettings(){//軟件的所有使用狀態(tài)都是用通過QSettings來保存的}圖5-8導(dǎo)入設(shè)置代碼圖//保存設(shè)置voidsaveSettings();圖5-9保存設(shè)置代碼圖//任務(wù)出錯voidtorrentError(TorrentClient::Errorerror){//如果在下載過程出現(xiàn)錯誤,提示錯誤圖5-10出錯處理代碼圖//添加TorrentbooladdTorrent();//刪除任務(wù)voidremoveTorrent(int){主要是將所選的任務(wù)斷開連接}//暫停任務(wù)voidpauseTorrent(int){ //將任務(wù)狀態(tài)設(shè)為暫停}//任務(wù)中斷voidtorrentStopped();}//更新任務(wù)狀態(tài)voidupdateState(TorrentClient::Statestate);//更新PEER信息voidupdatePeerInfo();//更新進(jìn)度條voidupdateProgress(intpercent);//更新下載速度voidupdateDownloadRate(intbytesPerSecond);//更新上載速度voidupdateUploadRate(intbytesPerSecond);//voidacceptFileDrop(constQString&fileName);//通過限制socket來現(xiàn)在下載和上傳速度//設(shè)置最大上傳速率限制voidsetUploadLimit(intbytes);//設(shè)置最大下載速率限制voidsetDownloadLimit(intbytes);系統(tǒng)測試測試概述G.J.Myers在他的名著《軟件測試技巧》一書中,給出了測試的定義:“程序測試是為了發(fā)現(xiàn)錯誤而執(zhí)行程序的過程”。根據(jù)這一定義,測試(Testing)的目的與任務(wù)可以描述為:目的:發(fā)現(xiàn)程序的錯誤;任務(wù):通過在計算機上執(zhí)行程序,暴露程序中潛在的錯誤。另一個與測試有關(guān)的術(shù)語叫糾錯(Debugging)。它的目的與任務(wù)可以規(guī)定為:目的:定位和糾正錯誤;任務(wù):消除軟件故障,保證程序的可靠運行。測試與糾錯的關(guān)系,可以用圖7.1的數(shù)據(jù)流圖來說明。圖中表明,每一次測試都要準(zhǔn)備好若干必要的測試數(shù)據(jù),與被測試程序一道送入計算機執(zhí)行。通常把程序執(zhí)行需要的測試數(shù)據(jù),稱為一個“測試用例(TestingCase)”。每一個測試用例產(chǎn)生一個相應(yīng)的“測試結(jié)果”。如果它與“期望結(jié)果”不相符合,便說明程序中存在錯誤,需要用糾錯來改正。對于長度僅有數(shù)百行的小程序,測試與糾錯一般由編碼者一人完成;但對于大型的程序,測試與糾錯必須分開進(jìn)行。為了保證大程序的測試不受干擾,通常都把它交給獨立的小組進(jìn)行,等發(fā)現(xiàn)了程序有錯誤,再退回編碼者進(jìn)行糾錯。有人把小程序得測試和糾錯合稱為“調(diào)試”。一旦編好了一個小程序,先拿到機器上測試,發(fā)現(xiàn)錯誤便進(jìn)行糾錯,修改后再重復(fù)測試。這一交替進(jìn)行的“測試-糾錯-再測試-再糾錯”的過程,常被通俗的稱為“調(diào)試程序”。其實“調(diào)試”在英語中并無相當(dāng)?shù)脑~,但糾錯時有一種常用的工具叫“Debugger”,通常被稱為調(diào)試程序,而不譯為糾錯程序。測試特性與分析、設(shè)計、編碼等工作相比,程序測試具有若干特殊的性質(zhì)。了解這些性質(zhì),將有助于我們正確處理和做好測試工作。挑剔性測試時對質(zhì)量的監(jiān)督與保證,所以“挑剔”和“揭短”很自然的成為測試人員奉行的信條。測試是為了證明程序有錯,而不是證明程序無錯。因此,對于被測程序就是要“吹毛求疵”,就是要在“雞蛋里面挑骨頭”。只有抱著為證明程序有錯的目的去測試,才能把程序中潛在的大部分錯誤找出來。復(fù)雜性人們常常以為開發(fā)一個程序是困難的,測試一個程序則是比較容易的,這其實是誤解。設(shè)計測試用例是一項需要細(xì)致和高度技巧的工作,稍有不慎就會顧此失彼,發(fā)生不應(yīng)有的疏漏。舉一個極簡單的例子。假如一個程序的功能是輸入3個數(shù)作為三角形的3條邊,然后鑒別這一三角形的類別。輸入3個”5”時程序回答“等邊三角形”,但若輸入3個“0”程序也回答“等邊三角形”,就真假不分了。又如,三條便分別為2、3、4時應(yīng)判斷是“不等邊三角形”,但如果對2、3、5或2、3、6也判斷為“不等邊三角形”,也會鬧笑話??梢娫谠O(shè)計測試用例時,需要考慮到各種可能出現(xiàn)的情況,對被測程序進(jìn)行多方面的考核。切忌掛一漏萬,把原本復(fù)雜的問題想的過于簡單。小程序尚且如此,大型程序就可想而知了。所以有人認(rèn)為,搞好一個大型程序的測試,其復(fù)雜性不亞于對這個程序的開發(fā),主張?zhí)暨x最有才華的程序員來參加測試工作。不徹底性“程序測試只能證明錯誤的存在,但不能證明錯誤不存在”。這句話揭示了測試所固有的一個重要性質(zhì)――不徹底性。可能有人認(rèn)為,測一遍不徹底可以測十遍,十遍不徹底可以測百遍。需要多少測試用例就用多少測試用例,難道還怕達(dá)不到徹底嗎?為了回答這個問題,舉一個例子。假如有人開發(fā)了一個C語言的編譯程序,要對它進(jìn)行徹底的測試,需要設(shè)計多少個測試用例呢?從正面說,該編譯程序應(yīng)能把一切符合語法的C程序正確的翻譯為目標(biāo)程序;從反面說,它應(yīng)能對一切有語法錯誤的C程序指出程序的語法。顯然,這兩個“一切都是無窮量”,十無法實現(xiàn)的。所謂徹底測試就是讓被測程序在一切可能的輸入情況下全部執(zhí)行一遍。通常稱這種測試為“窮舉測試(ExhaustiveTesting)”。實際測試中,窮舉測試要不是像上例那樣根本無法實現(xiàn),就是工作量太大(例如一個小程序要連續(xù)測試許多年),在實踐上行不通。這就注定了一切實際測試都是不徹底的,當(dāng)然也就不能保證測試后的程序不存在遺留的錯誤。經(jīng)濟性既然窮舉測試行不通,所以在程序測試中,總是選擇一些典型的、有代表性的測試用例,進(jìn)行有限的測試。通常把這種測試稱為“選擇測試(SelectiveTesting)”,為了降低測試成本(一般占整個開發(fā)成本的1/3左右),選擇測試用例時應(yīng)注意遵守“經(jīng)濟性”的原則。所以,第一,要根據(jù)程序的重要性和一旦發(fā)生故障將造成的損失開確定它的可靠性等級,不要隨意提高等級,從而增加測試的成本;第二,要認(rèn)真研究測試策略,以便能使用盡可能少的測試用例,發(fā)現(xiàn)盡可能多的程序錯誤。測試種類測試是一個執(zhí)行程序的過程,即要求被測程序在機器上運行。其實,不執(zhí)行程序也可以發(fā)現(xiàn)程序的錯誤。為便于區(qū)分,一般把前者稱為“動態(tài)測試”,后者稱為“靜態(tài)分析(StaticAnalysis)”。廣義的說,它們都屬于程序測試。顧名思義,靜態(tài)分析就是通過對被測程序的靜態(tài)審查,發(fā)現(xiàn)代碼中潛在的錯誤。它一般用人工方式脫機完成,故亦稱為人工測試或代碼評審(CodeReview);也可借助于靜態(tài)分析器在機器上以自動方式進(jìn)行檢查,但不要求程序本身在機器上運行。按照評審的不同組織形式,代碼評審又可區(qū)分為代碼會審、走查盒辦公桌檢查3種。對某個具體的程序,通常只使用一種評審方式。代碼會審是由一組人通過閱讀、討論和爭議對程序進(jìn)行靜態(tài)分析的過程。會審小組由組長,2~3名程序設(shè)計和測試人員及程序員組成。會審小組在充分閱讀待審程序文本、控制流程圖及有關(guān)要求、規(guī)范等文件基礎(chǔ)上,召開代碼會審會,程序員逐句講解程序的邏輯,并展開熱烈的討論甚至爭議,以揭示錯誤的關(guān)鍵所在。實踐表明,程序員在講解過程中能發(fā)現(xiàn)許多自己原來沒有發(fā)現(xiàn)的錯誤,而討論和爭議則進(jìn)一步促使了問題的暴露。例如,對某個局部性小問題修改方法的討論,可能發(fā)現(xiàn)與之有牽連的甚至能涉及到模塊的功說明、模塊間接口和系統(tǒng)總結(jié)構(gòu)的大問題,導(dǎo)致對需求定義的重定義、重設(shè)計驗證,大大改善了軟件的質(zhì)量。動態(tài)測試也可區(qū)分為兩種。一類把被測程序看成一個黑盒,根據(jù)程序的功能來設(shè)計測試用例,稱為黑盒測試(BlackBoxTesting);另一類則根據(jù)被測程序的內(nèi)部結(jié)構(gòu)設(shè)計測試用例,測試者需事先了解被測程序的結(jié)構(gòu),故稱為白盒測試(WhiteBoxTesting)。結(jié)論在2014年2月份,我開始了我的畢業(yè)論文工作,通過兩個多月的折騰,總算把畢業(yè)設(shè)計給完成了。論文的寫作是一個艱苦而又漫長的過程,需要不斷的進(jìn)行精心的修改,不斷地去研究各方面的文獻(xiàn),認(rèn)真總結(jié),雖然過程有些坎坷,經(jīng)歷將近2個月的努力,終于完成了畢業(yè)論文。在這次畢業(yè)論文的寫作的過程中,我擁有無數(shù)難忘的感動和收獲。記得大概是去年的12月份左右,拿到這個畢業(yè)設(shè)計的題目,當(dāng)時心中咯噔一下,雖然以前也寫過不是代碼,但是對于BT下載來說還是感到十分陌生,可以說基本沒有任何印象。對于該題目沒有任何頭緒的我,開始是上網(wǎng)查詢關(guān)于BitTorrent協(xié)議的信息,漸漸開始熟悉了BitTorrent協(xié)議。說白了還是計算機與計算機之間進(jìn)行通信,只是通信的時候需要遵守一些規(guī)定,規(guī)定怎么獲取peer,怎么分配peer等等。大致Bt下載過程就是,BT首先在上傳者端把一個文件分成了Z個部分,甲在服務(wù)器隨機下載了第N各部分,乙在服務(wù)器隨機下載了第M個部分,這樣甲的BT就會根據(jù)情況到乙的電腦上去拿乙已經(jīng)下載好的M部分,乙的BT就會根據(jù)情況去到甲的電腦上去拿甲已經(jīng)下載好的N部分,這樣就不但減輕了服務(wù)器端得負(fù)荷,也加快了用戶方(甲乙)的下載速度,效率也提高了,更同樣減少了地域之間的限制。比如說丙要連到服務(wù)器去下載的話可能才幾K,但是要是到甲和乙的電腦上去拿就快得多了。所以說用的人越多,下載的人越多,大家也就越快,BT的優(yōu)越性就在這里。而且,在你下載的同時,你也在上傳(別人從你的電腦上拿那個文件的某個部分),所以說在享受別人提供的下載的同時,你也在貢獻(xiàn)。了解BitTorrent協(xié)議工作原理之后,然后就是每天上網(wǎng)查資料了解QT的信號與槽機制,了解窗體與窗體之間是怎么進(jìn)行通信的,開始了解種子文件的解析代碼,編寫相應(yīng)的種子類,保存種子的信息,了解客戶端怎么與Tracker服務(wù)端通信,還有就是peer與peer怎么通信,編寫相應(yīng)的類,最后開始編寫搭建軟件界面框架嗎,之后每天只要有時間就抽出來試著寫,一步一步,在查閱參考其他人的代碼下,慢慢寫出了基本能夠?qū)崿F(xiàn)基本功能的軟件,從一個對這個知識毫無了解慢慢學(xué)會了下載知識,這本身就是對新知識學(xué)習(xí)和能力的提高!這次畢業(yè)設(shè)計加深我對QT的認(rèn)識以及C++的學(xué)習(xí)認(rèn)識,更加清楚地了解到了QT中核心和精華,信號與槽機制,更加深刻的了解到面向?qū)ο蟪绦蛟O(shè)計的開發(fā)模式。我深刻的認(rèn)識到要想成為一名合格且牛逼的C++軟件工程師還需要很長的路要走,并且很艱難,但我相信每次的軟件開發(fā)都是對自我軟件水平的檢驗和提升,可以看到自己的不足,當(dāng)你能認(rèn)識到這一點的時候也許就自我的提升和學(xué)習(xí)新知識的動力,希望自己在以后的道路上,走得越來越從容。參考文獻(xiàn)王曉凱.基于P2P多播發(fā)現(xiàn)的FTPSERVER及FTP調(diào)度優(yōu)化[D].鄭州大學(xué),2003年劉保言.對等(P2P)網(wǎng)絡(luò)搜索技術(shù)的研究[D].重慶大學(xué),2004年孫默.P2P網(wǎng)絡(luò)安全模型的研究與設(shè)計實現(xiàn)[D].西安電子科技大學(xué),2005年陸垂偉;紀(jì)鵬;王再明.一種新型網(wǎng)絡(luò)技術(shù)——P2P網(wǎng)絡(luò)模型[J].黃石理工學(xué)院學(xué)報,2006年03期李智昕,董健全,李威.新的匿名通信機制:基于P2P的匿名Socket的研究[J].計算機工程與應(yīng)用,2004年15期何春,張再萍,張鷹.P2P網(wǎng)絡(luò)技術(shù)的研究及應(yīng)用[J].電腦學(xué)習(xí),20

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論