BT協(xié)議簡介
在互聯(lián)網(wǎng)上下載文件的方式大概有這么幾種:FTP、HTTP、BT、eMule(電驢)等, 閱讀器會直接支持FTP和HTTP下載,BT和eMule下載1般需要專用的下載軟件的支持。
接下來分別簡單介紹1下他們的區(qū)分:
FTP 是 File Transfer Protocol(文件傳輸協(xié)議)的英文簡稱,顧名思義,就是提供文件傳輸?shù)?個(gè)協(xié)議。首先需要有1個(gè)FTP Server,負(fù)責(zé)文件的存儲并接受網(wǎng)絡(luò)要求(FTP連接和指令)提供下載,然后FTP Client 向FTP Server發(fā)起網(wǎng)絡(luò)要求,并將接遭到的文件內(nèi)容保存到本地。
HTTP是HyperText Transfer Protocol (超文本傳輸協(xié)議)的英文簡稱,超文本就是我們平時(shí)所說的網(wǎng)頁,通過網(wǎng)頁上的鏈接把眾多的網(wǎng)頁組織成1個(gè)超級大的信息節(jié)點(diǎn)網(wǎng)絡(luò),所以叫超級文本。文件下載只是HTTP協(xié)議所支持的1個(gè)子功能,一樣需要HTTP Server (Nginx、Apache、IIS等)和 HTTP Client (各種閱讀器)來完成文件的下載。
對以上兩種下載方式做1個(gè)簡單總結(jié):
Client連接到指定的Server(HTTPServer、FTPServer)下載文件 。
如果用戶想要更快的下載速度呢?
1種選擇是,Client使用多線程下載,搶占更多的服務(wù)器資源(初期的網(wǎng)際快車FlashGet就是這類方式)。
如果用戶量很大,這樣無疑對Server造成很大的壓力。然后呢,Server提供商(網(wǎng)站方)需要提供更多的服務(wù)器和更高的帶寬,但是這需要花很多錢。
那末,有無更低本錢的解決方案呢?接下來就出現(xiàn)了BT下載。
BT是BitTorrent的縮寫,Torrent是激流、洪流的意思,Bit洪流,看名字就很牛的模樣。和以上兩種下載方式最大的區(qū)分就是用戶不再直接從服務(wù)器下載文件,而是用戶之間相互下載,這類方式叫做P2P (Peer to Peer 點(diǎn)對點(diǎn))。
參與的人越多,下載速度越快
要做到P2P下載首先需要解決以下兩個(gè)問題:
1、 如何知道哪些Client在下載同1個(gè)文件?
2、 對某1個(gè)文件,如何做到同時(shí)從多個(gè)來源進(jìn)行下載?
對第1個(gè)問題的解決方案:
設(shè)計(jì)1個(gè)TrackerServer(跟蹤服務(wù)器),每個(gè)Client需要去這里上報(bào)自己正在下載的文件和自己的ip地址和監(jiān)聽的端口。新來的Client先要連接到TrackerServer,根據(jù)要下載的文件查詢當(dāng)前正在下載這個(gè)文件的Clients (Peers)。
對第2個(gè)問題的解決方法:
Client從TrackerServer獲得Peers后,分別向他們發(fā)起連接并詢問當(dāng)前的下載進(jìn)度,然后,同時(shí)連接多個(gè)Peers分別下載他們已完成的文件片斷,最后拼接出完全的文件。
那末對下載進(jìn)度應(yīng)當(dāng)如何表達(dá)呢?
由于文件不是被順序下載的(由于需要從Peers同時(shí)下載不同的片斷),所以不可以通過當(dāng)前已完成的字節(jié)數(shù)來表示進(jìn)度。
那末,最簡單有效的方式就是把文件分割成相同大小的片斷(Piece),片斷的大小1般是2^n,比如2^18=256K,通過已完成Pieces的序號列表來表示當(dāng)前的下載進(jìn)度。
另外,由于Pieces序號是連續(xù)的,可以通過BitMap的方式表示每一個(gè)Piece Index是不是已完成。Piece Index所在的bit位為1,表示該P(yáng)iece已下載完成。
如果下載任務(wù)是1個(gè)文件夾(包括很多文件), 可以把這些文件依照固定的順序連接起來(邏輯上)進(jìn)行Pieces切分。
當(dāng)Client獲得到Peers的完成列表后,就能夠?qū)⒉煌腜ieces分配到對應(yīng)的Peers進(jìn)行并行下載,同時(shí)將自己已完成的Pieces提供給其他Peers來下載。
互幫互助、互通有沒有的和諧社會就此開啟了。
到目前為止,我們還有幾個(gè)關(guān)鍵問題沒有解決:
1、怎樣找到待下載文件的TrackerServer?
2、Peers對文件分片的規(guī)則是不是1致?
3、在TrackerServer上怎樣唯1的標(biāo)識1個(gè)下載任務(wù)?
4、下載來的Pieces是不是在傳輸進(jìn)程中出現(xiàn)了毛病或被歹意篡改?
為了解釋上面的問題,此處應(yīng)當(dāng)有.torrent文件(BT種子)出場了。作為老司機(jī),你那30G的種子有無鑒賞過里面都是甚么數(shù)據(jù)呢?
BT種子文件主要包括以下關(guān)鍵信息:
名字 |
類型 |
意義 |
announce |
String |
TrackerServer的地址 |
announce-list |
List of list |
TrackerServer分組列表 |
info |
Dict (kv集合) |
包括了待下載文件的基本信息:
如文件名稱、目錄名稱、分片大小、分片SHA1哈希值等。 |
publisher |
String |
種子發(fā)布者名稱 |
publisher-url |
String |
種子發(fā)布者URL |
nodes |
List |
DHT(散布式哈希表)的節(jié)點(diǎn)列表, 咋就 DHT Protocol中定義, 類似于eMule的Kad網(wǎng)絡(luò),實(shí)現(xiàn)了Trackerless。 |
encoding |
String |
種子文件的字符編碼,如 UTF⑻ |
… |
… |
和其他擴(kuò)大信息 |
我們找1個(gè)種子文件片斷來瞧1下:
是否是有似曾相識卻又看不懂的感覺呢?這是由于.torrent文件是bencoding編碼表示的。
bencoding編碼是1種對象序列化表示法(功能和json是1樣的,但是規(guī)則不1樣),bencoding 編碼通過開頭的字符來指定接下來的對象的類型,規(guī)則以下:
'd'開頭表示是dict類型,可以理解為key=>value的集合,'e'表示結(jié)束
'l'(小寫字母L)開頭表示是list類型,'e'表示結(jié)束
'i' 開頭表示是integer類型,'e'表示結(jié)束,可以表示負(fù)數(shù)
數(shù)字 開頭表示string類型,數(shù)字為string的長度,長度與string內(nèi)容以':'分割開
上圖中標(biāo)注的地方8:encoding5:UTF⑻4:infod5:files,依照這個(gè)規(guī)則解析后得到
encoding=>UTF⑻
info => { files=> …}
至此,總結(jié)1下BT下載的基本進(jìn)程, 聰明的你是不是已了解BT下載了呢?
---------------------------------------------------------我是分割線---------------------------------------------------------------
接下來是對BT 協(xié)議的1些細(xì)節(jié)描寫,對細(xì)節(jié)感興趣的話可以繼續(xù)看1下
TrackerServer有HTTP和UDP協(xié)議兩種,這里簡單介紹1下HTTP協(xié)議的TrackerServer,BTClient通過 HTTP Get要求完成Peers獲得和本身的注冊。要求的URL格式以下:
Trackerserver-url?info_hash=xxxxxxxxxxxx,peer_id=xxxxxxxxxxx,ip=x.x.x.x,port=xxxx,uploaded=xx,downloaded=xx,left=xx,event=x
URL中各參數(shù)需要經(jīng)過urlencode處理,各個(gè)參數(shù)的意義以下:
參數(shù)名稱 |
參數(shù)意義 |
info_hash |
torrent文件中info屬性的value部份(bencode格式)的SHA1 哈希值,這個(gè)哈希值是BT下載任務(wù)的唯1標(biāo)識。 |
peer_id |
任務(wù)啟動(dòng)時(shí)BT Client為自己隨機(jī)分配的20字節(jié)的ID |