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