1. 程式人生 > >計算機網路--詳解P2P對等網路(一)—BitTorrent協議

計算機網路--詳解P2P對等網路(一)—BitTorrent協議

注:本篇文章內容借鑑自:淺入淺出BitTorrent協議,其中加入了博主的部分原創,感謝,侵刪~

對等網路的概念

以下定義主要摘抄自維基百科與中科院計算技術研究所:

對等式網路(peer-to-peer,簡稱P2P),又稱點對點技術,是無中心伺服器、依靠使用者群(peers)交換資訊的網際網路體系。它的作用在於,網路的參與者共享他們所擁有的一部分硬體資源(處理能力、儲存能力、網路連線能力、印表機等),這些共享資源通過網路提供服務和內容,能被其它對等節點(Peer)直接訪問而無需經過中間實體,減低以往網路傳輸中的節點,以降低資料遺失的風險。與有中心伺服器的中央網路系統不同,對等網路中的每個使用者端既是資源(服務和內容)提供者(Server),又是資源獲取者(Client),任何一個節點無法直接找到其他節點,必須依靠其使用者群進行資訊交流。

對等網路的模型

P2P網路的簡易模型圖如下:

此處輸入圖片的描述

如圖,我們可以總結出P2P網路的一些特徵:

  1. 非中心化:P2P是全分散式系統,網路中的資源和服務分散在所有的節點上,資訊的傳輸和服務的實現都直接在節點之間進行,可以無需中間環節和伺服器介入。
  2. 可擴充套件性:使用者可以隨時加入該網路,系統的資源和服務能力隨之同步擴充。理論上其可擴充套件性幾乎可以認為是無限的。
  3. 健壯性:因為服務是分散在各個節點之間的,部分節點或網路遭到破壞對其他部分的影響很小,故P2P具有耐攻擊、高容錯的特點。P2P網路一般在部分結點失效時能夠自動調整整體拓撲,保持其它結點的連通性。P2P網路通常都是以自組織的方式建立起來的,並允許結點自由地加入和離開。
  4. 高性價比:P2P架構可以有效地利用網際網路中散佈的大量普通結點,將計算任務或儲存資料分佈到所有結點上。利用其中閒置的計算能力或儲存空間,達到高效能運算和海量儲存的目的。
  5. 隱私保護:在P2P網路中,由於資訊的傳輸分散在各節點之間進行而無需經過某個集中環節,使用者的隱私資訊被竊聽和洩漏的可能性大大縮小。
  6. 負載均衡:由於每個節點既是伺服器又是客戶端,減少了傳統C/S模型中對伺服器計算能力、儲存的要求,同時因為資源分佈在多個節點,更好的實現了整個網路的負載均衡。

BitTorrent協議

BitTorrent協議,簡稱BT協議,是一種網際網路上新興的P2P傳輸協議(即BT是一種特殊的P2P)。

出現的歷史原因

隨著全球接入網際網路人數的增長,對網際網路應用的服務端要求越來越高,吞吐量和併發量逐步加大。像國外的Google、Amazon,國內的阿里、百度等大型網際網路企業十分關注如何使用叢集、負載均衡等技術來提高網站的併發和吞吐量。但對於儲存大檔案給使用者下載的中小型網站,在網際網路爆發式增長下,使用者數量越來越多,傳輸的檔案越來越大,使用一臺或幾臺伺服器和傳統的FTP、HTTP協議難以滿足使用者對下載速度的需求(受限於龐大的使用者請求量、硬碟讀取速度、頻寬等)。BitTorrent協議解決了這些問題。

BT下載流程

無論是BT還是PT,還是FTP,都是一種下載方式,或者學術點的講法,叫檔案傳輸。

BT下載通過一個P2P下載軟體(點對點下載軟體)來實現,克服了傳統下載方式的侷限性,具有下載的人越多,檔案下載速度就越快的特點。其好處是不需要資源釋出者擁有高效能伺服器就能迅速有效地把釋出的資源傳向其他的BT客戶軟體使用者,而且大多數的BT軟體都是免費的。

BT下載架構模型圖:

此處輸入圖片的描述

現在,我們已經清楚了BT下載的架構模型,對於BT下載流程的討論,我們跟隨BT協議所引出的三個問題來進行:

  1. 一個對等使用者如何找到具有自己想下載內容的其他對等使用者?
  2. 對等使用者們如何複製內容以便為大家提供高速下載?
  3. 對等使用者們如何相互鼓勵上傳內容給他人同時為自己下載內容?

1. B encode

在解決這三個問題之前,先簡單介紹下B encode,因為在BitTorrent協議中的資料幾乎都是用B encode進行編碼的。它是一種作用類似於XML和JSON的資料組織格式,可以表達字串、整數兩種基本型別,列表、字典兩種資料結構,它的語法規則十分簡單。

  • 位元組串按如下方式編碼:

<以十進位制ASCII編碼的串長度>:<串資料>
例:“4:spam”表示位元組串“spam”

  • 整數按如下方式編碼:

i<以十進位制ASCII編碼的整數>e
例:“i3e”表示整數“3”

  • 列表按如下方式編碼:

l<內容>e
開始的“l”與結尾的“e”分別是開始和結束分隔符。lists可以包含任何B編碼的型別,包括整數、串、dictionaries和其他的lists。
例:l4:spam4:eggse 表示含有兩個串的lists:[“spam”、“eggs”]

  • 字典按如下方式編碼:

d<內容>e
開始的“d”與結尾的“e”分別是開始和結束分隔符。注意鍵(key)必須被B編碼為串。值可以是任何B編碼的型別,包括整數、串、lists和其他的dictionaries。鍵(key)必須是串,並且以排序的順序出現(以原始串排列,而不是以字母數字順序)。
例:d3:cow3:moo4:spam4:eggse表示dictionary { “cow” => “moo”, “spam” => “eggs” }

2. torrent檔案與tracker伺服器

現在,我們考慮上述中的第一個問題:一個對等使用者如何找到具有自己想下載內容的其他對等使用者?

在P2P網路系統的最初階段,並不是所有的使用者都擁有所有的內容,首先需要一個內容的釋出者。作為內容的釋出者,BitTorrent可以為每個釋出者(內容提供商)建立一個內容描述檔案,即.torrent檔案,也就是我們平常所說的種子檔案

種子檔案是一種指定格式的檔案,包含了兩類關鍵資訊,一類資訊是tracker伺服器的URL,一類資訊是一個大小相等的塊的清單。tracker伺服器可以將使用者引導至種子檔案的內容,也就是將使用者引導至擁有當前使用者所需下載內容的其他對等節點處,塊清單則組成了內容。

關於種子檔案具體的組成結構,它使用B encode表示,整個是一個字典資料結構,它有多個key值,包括一些是可選的,這裡介紹最關鍵的上述兩類資訊的鍵值對:

  • info:儲存資原始檔的元資訊
    • piece length
    • pieces
    • name/path
  • announce:描述tracker伺服器的URL

info:info鍵對應的值又是一個字典結構,BT協議將一個檔案分成若干塊,便於客戶端從各個主機下載各個塊。其中的piece length鍵值對錶示一個塊的長度,通暢情況下是2的n次方,根據檔案大小有所權衡,通長越大的檔案piece length越大以減少piece的數量,降低piece數量一方面降低了種子檔案儲存塊資訊數目的大小,一方面也減少了下載時需要對塊做的確認操作,加快下載速度。目前塊的大小通常是256KB,512KB或者1MB。

pieces:表示每個塊的正確性驗證資訊,每一塊均對應一個唯一的SHA1雜湊值。該鍵對應的值是所有塊的SHA1雜湊值(每個塊所對應的雜湊值大小為20位元組)連線而成的字串。

name/path:表示具體檔案的資訊。因為BitTorrent協議允許將數個檔案和資料夾作為一個BT下載進行釋出,因此下載方可以根據需要勾選某一些下載檔案。注意,這裡將數個檔案也砍成一個數據流,因此一個piece如果在檔案邊界上,可能包含不同檔案的資訊。

announce:儲存的是tracker伺服器的URL,在一些擴充套件協議中,announce可以儲存多個tracker伺服器作為備選。

生成好種子檔案之後,為了下載由種子檔案所描述的內容,一個對等使用者首先需要和此種子檔案取得聯絡。這個種子檔案通常被放在伺服器上,可以通過HTTP或者FTP協議供使用者下載這個種子檔案。相比於直接將整個資原始檔提供給使用者下載,只傳輸一個種子檔案大大降低了伺服器的負荷。

在取得種子檔案後,我們可以通過BitTorrent協議提供的一些工具(BitTorrent軟體客戶端)來開啟這個種子檔案,客戶端會根據種子檔案的name/path元資訊告訴我們這個種子檔案可以下載到(假設)一個.mkv檔案,一個字幕檔案,在這個階段我可以進行一些勾選,選擇下載某些而不是全部的資源。

資源選擇確定後,客戶端就開始了下載。客戶端的第一步任務根據種子檔案上的tracker伺服器的URL使用HTTP進行GET請求——tracker伺服器維護著一個正在主動上傳和下載該內容的所有其他對等使用者列表,我們將這一組對等使用者稱為使用者群,對等使用者可以隨時離開群(以及返回),只要他們及時向tracker伺服器進行報告即可——這個請求包含了很多引數,這裡只介紹從客戶端傳送到tracker的請求中最關鍵的幾個引數。

  • info_hash
  • peer_id
  • ip
  • port

info_hash:種子檔案中info鍵所對應的值的SHA1雜湊,可以被tracker伺服器用來索引唯一的對應資源。

peer_id:20Byte的串,沒有任何要求,被tracker伺服器用於記錄客戶端的名字。

ip:可以從HTTP GET請求中直接獲取,放在引數中可以解決使用代理進行HTTP GET的情況,tracker伺服器可以記錄客戶端的IP地址。

port:客戶端監聽的埠號,用於接收Response。一般情況下為BitTorrent協議保留的埠號:6881-6889,tracker伺服器會記錄下埠號用於通知其他客戶端。

在tracker伺服器收到客戶端的HTTP GET請求後,會返回B encode形式的text/plain文字,同樣是一個字典資料結構,其中最關鍵的一個鍵值對是peers,它的值是個字典列表結構,列表中的每一項都是如下的字典結構:

  • peers
    • peer_id
    • ip
    • port

這些資訊在每個客戶端連線tracker伺服器的時候都發送過,並且被Tracker伺服器儲存了下來。新來的客戶端自然要獲取到這些下載中或者已下載完的客戶端的ip,port等資訊,有了這些資訊,客戶端就不需要像FTP或者HTTP協議一樣持續找伺服器獲取資源,可以從這些其他客戶端上請求獲取資源。

3. peer to peer

如上所述,如果對第一個問題進行簡單的總結,那麼自己想要下載的內容就交由種子檔案進行確定,而如何尋找擁有這些資源的其他對等使用者,則需要tracker伺服器的幫助。

那麼,我們現在思考第二個問題:對等使用者們如何複製內容以便為大家提供高速下載?

客戶端從tracker伺服器獲取到若干其他下載者(peer)的ip和port資訊,會進行請求並維持跟每一個peer的連線狀態。一個客戶端和每一個peer的狀態主要有下列狀態資訊:

  • choke:遠端客戶端拒絕響應本客戶端的任何請求。
  • interested:遠端客戶端對本客戶端的資料感興趣,當本客戶端unchoked遠端客戶端後,遠端客戶端會請求資料。

所以應該有4個引數,分別表示本客戶端對遠端客戶端是否choke,是否interested,遠端客戶端對本客戶端是否choke,是否interested。當一個客戶端對一個遠端peer感興趣並且那個遠端peer沒有choke這個客戶端,那麼這個客戶端就可以從遠端peer下載塊(block)。當一個客戶端沒有choke一個peer,並且那個peer對這個客戶端感興趣時,這個客戶端就會上傳塊(block)。

補充一點:由於內容釋出者本來就擁有所有的塊,因此在生成種子檔案的時候,內容釋出者首先會根據種子檔案將內容重新下載一遍,在這個過程中就會聯絡tracker伺服器,然後將自己的資訊記錄在其所維護的使用者列表上。

其實上述所講的概念已經解答了第二個問題,每一個對等節點在參與一個使用者群期間,都可同時從其他對等節點處下載缺少的塊,並給其他對等節點上傳本身擁有並且他們所需要的塊。如果每個對等節點都這樣做,那麼經過短暫的一段時間後,所有的塊都將成為廣泛可用——加入使用者群的使用者越多,塊被交易的越頻繁,下載速度越快。

對第二個問題的答案進行一個簡單的總結:對等使用者們通過在下載塊的同時也會上傳塊,從而為大家提供高速下載。

我們再進行一些補充,上面也提到了,在交易塊的過程中,端與端之間會進行通訊:

首先會發送握手報文,告訴遠端客戶端本客戶端的一些資訊,包括info_hash和peer_id。

接下來的所有報文有如下幾種型別:

  • keep-alive:告訴遠端客戶端這個通訊還在維持,否則超過2分鐘沒有任何報文遠端客戶端會將通訊關閉
  • choke
  • unchoke
  • interested
  • not interested
  • bitfield:告訴對方我已經有的piece
  • have:告訴對方某個piece已經成功下載並且通過hash校驗
  • request:請求某個塊(block)
    • index: 整數,指定從零開始的piece索引
    • begin: 整數,指定piece中從零開始的位元組偏移
    • length: 整數,指定請求的長度
  • piece:返回請求的塊(block)的資料,是真正的資源資訊
    • index: 整數,指定從零開始的piece索引
    • begin: 整數,指定piece中從零開始的位元組偏移
    • block: 資料塊

經過這些報文在本地客戶端和若干個遠端客戶端之間的來回傳遞,就能夠獲取到資原始檔。

4. PT下載

在解決了前兩個問題之後,我們來考慮第三個問題:對等使用者們如何相互鼓勵上傳內容給他人同時為自己下載內容?

我們也可以看到,在P2P網路中,起初必須有一個內容的提供者,並且在健康的P2P網路中,每個peer都應當同時扮演客戶端與伺服器兩個角色,那些只想從系統中獲取資源而沒有實物貢獻的節點我們稱之為“搭便車”或“吸血鬼”,如果這樣的使用者太多,那系統將無法正常工作。

PT全稱Private Tracker,與BT最大的不同點分別為可進行私密範圍下載,及可統計每個使用者的上傳及下載量。從技術上可以簡單的看作有一個tracker伺服器會對使用者的下載上傳進行統計,分享率不夠就禁止使用者下載,在一定程度上可以防止只下載而不上傳的使用者存在。關於PT下載更詳細的內容,博主不在這裡進行討論,有興趣的同學可以自行查閱相關資料。

一個有趣的小問題

迅雷作為國內首屈一指的BT下載工具,為什麼有時在下載接近完成的最後,一些資料總是傳輸的非常慢呢?

基於現實情況分析,有些人下載完成後關掉下載任務,提供較少量資料給其他使用者,為儘量避免這種行為,在非官方BitTorrent協議中存在超級種子的演算法。這種演算法允許檔案釋出者分幾步釋出檔案,釋出者不需要一次提供檔案所有內容,而是慢慢開放下載內容的比例,延長下載時間。此時,速度快的人由於未下載完必須提供給他人資料,速度慢的人有更多機會得到資料。由此往往造成使用者卡在任務的99%,下載1G的任務要上傳3G之多的資料。

總結

  1. 熟悉P2P網路的特點及優勢;
  2. 熟悉BitTorrent協議的基本內容;
  3. 熟悉BT下載的過程(種子檔案以及tracker伺服器);
  4. 掌握諸如使用者群吸血鬼等名詞含義;
  5. 瞭解種子檔案的組成格式——B編碼;
  6. 瞭解peer與peer之間的通訊報文格式;
  7. 能獨立回答出關於BitTorrent協議的三個問題。

參考閱讀

計算機網路(第五版) — Andrew S. TanenBaum/David J. Wetherall