1. 程式人生 > >從零開始編寫一個BitTorrent下載器

從零開始編寫一個BitTorrent下載器

# 從零開始編寫一個BitTorrent下載器 ## BT協議 ### 簡介 > BT協議Bit Torrent(BT)是一種通訊協議,又是一種應用程式,廣泛用於對等網路通訊(P2P)。曾經風靡一時,由於它引起了巨大的流量,對因特網的運營、維護和管理都產生了重要的影響。 BT協議的典型特徵就是沒有中心伺服器。BT協議中,作為參與者的機器被稱為**peers**。**peer**之間的通訊協議又被稱為**peer wire protocal**,即**peer連線協議**,是一個基於TCP協議的應用層協議。 BT協議在20年裡不斷髮展(從2001年開始),加入加密、私有種子等設計,也擴充套件了搜尋peer主機的方法。 ### 連線 由於沒有中心伺服器,參與者需要使用另外的方法取得他人的地址,以建立對等連線,確定自己的機器應當從何處下載需要的檔案。傳統的BT協議使用中介伺服器**trackers**來告知每個參與者如何進行下載。**trackers**伺服器是基於HTTP的,這類伺服器本身不託管檔案資源,僅為每個參與者分配peers。 在BT協議網路中傳播違法資源的現象十分常見,這導致其中介伺服器常常會受到法律制裁,查封事件屢見不鮮。要解決這一問題,就需要將主機搜尋的工作下放到每個參與者的機器,即**分散式處理(distributed process)**。BT協議未來的核心就是[DHT](https://baike.baidu.com/item/DHT/1007999)、PEX、[磁力鏈](https://baike.baidu.com/item/磁力連結)。 ## \.torrent檔案解析 以debian釋出的映象檔案種子為例。 ![image](data:image/jpeg;base64,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VWigC1/aEn91fyP+NH9oSf3V/I/41VooAtf2hJ/dX8j/AI0f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/wCNVaKALX9oSf3V/I/40f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/41VooAtf2hJ/dX8j/AI0f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/wCNVaKALX9oSf3V/I/40f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/41VooAtf2hJ/dX8j/AI0f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/wCNVaKALX9oSf3V/I/40f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/41VooAtf2hJ/dX8j/AI0f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/wCNVaKALX9oSf3V/I/40f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/41VooAtf2hJ/dX8j/AI0f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/wCNVaKALX9oSf3V/I/40f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/41VooAtf2hJ/dX8j/AI0f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/wCNVaKALX9oSf3V/I/40f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/41VooAtf2hJ/dX8j/AI0f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/wCNVaKALX9oSf3V/I/40f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/41VooAtf2hJ/dX8j/AI0f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/wCNVaKALX9oSf3V/I/40f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/41VooAtf2hJ/dX8j/AI0f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/wCNVaKALX9oSf3V/I/40f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/41VooAtf2hJ/dX8j/AI0f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/wCNVaKALX9oSf3V/I/40f2hJ/dX8j/jVWigC1/aEn91fyP+NH9oSf3V/I/41VooAtf2hJ/d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vw3pWgaN4w8E2ekaXaxWVnb/APCH3z+VDGoRF3Nq5Y4UAZJJPc1riMVhfZVIUcTFylypylCS5kozTuuR2d5K2r1ipXukJQlzXa0107aR/VN/M4z4UeEfFHi3RYvFtl401ptatPGOqwtbajqc0lg+mxavcRSWxg5ViIVby3I3KQgDBF21ha9rnjzxF418bX2g6V441HV9F19bHSrjTtVsrfQ4YY0gZ4p7aS6Qy7t0hd2hdhvGxhgY9N8MfDf4leDdMk0/R/F/gmzs5Lq4vWj/AOEQvnzNPM88zZbVyfmkkdsZwM4AAAFc5rX7OXirxD4oPiC/1/wTNqLyxzzKvhbU47a5lj2+XJPbrrIimddq4aRGI2rg8CuylmOC+t1q1WtBxd+S8Juyck+VpKOltH7z3as0xVKc5RajdO/lt73r3XR7Lsg8aaNqfi3x18Vo/wDhLPEWjw6JpNhd6bFpOpSW6QXBhuGMhVTtcEouY2BRv4lbjGT8TvB8XxQ8M/BzxLquseILPUNUvNJSePSdburKAGSGSRpFiikVVkyxxIBuA4ziu1b4XfEZr/XL0+LfBP2nW4I7bUJP+ERv/wB9GiuqLj+18LgSOMrg8/SqGt/BPx14i8F2nhO+8U+C5NDs44Y7aGPwrqMUkHlACJkmTWBIrKAMMGDe9Y0cdhqM6Uo4pR5OVXUZ3S5FGVvcV7yV7X16tMXJNpq26mvvty/dqeu+F/DsPhPQbXSbe71C+htwQtxql7LeXDZYn55pWZ3645J4AHatWuR+FnhHVvAvhGDRNW1Wz1drV2FvNZ211FtiOCFc3N1cySPuLneZOhUYG3J66vhcTb283GfOrv3tVfzs9dTrhpFaWCiiiuYsKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAo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Ik/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJo8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJo8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJo8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJo8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJo8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJo8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJo8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJo8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJo8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJo8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJo8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJo8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJo8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJo8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJqa0idbhCUYDnkj2rSooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDH8iT/nm3/fJo8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAx/Ik/55t/3yaPIk/55t/3ya2KKAMfyJP+ebf98mjyJP8Anm3/AHya2KKAMfyJP+ebf98mjyJP+ebf98mtiigDNtInW4QlGA55I9qh8iT/AJ5t/wB8mtiigDH8iT/nm3/fJo8iT/nm3/fJrYooAx/Ik/55t/3yaPIk/wCebf8AfJrYooAhtFK26Agg88H60VNRQB//2Q==) 一個\.torrent檔案描述了可下載檔案的內容以及需要連線到的tracker中介伺服器的資訊,其編碼格式為**Bencode**。 檔案的頭部資訊可以直接以文字形式檢視: ``` d8:announce41:http://bttracker.debian.org:6969/announce7:comment35:"Debian CD from cdimage.debian.org"13:creation datei1612616380e9:httpseedsl146:https://cdimage.debian.org/cdimage/release/edu//srv/cdbuilder.debian.org/dst/deb-cd/weekly-builds/amd64/iso-cd/debian-edu-10.8.0-amd64-netinst.iso146:https://cdimage.debian.org/cdimage/archive/edu//srv/cdbuilder.debian.org/dst/deb-cd/weekly-builds/amd64/iso-cd/debian-edu-10.8.0-amd64-netinst.isoe4:infod6:lengthi425721856e4:name35:debian-edu-10.8.0-amd64-netinst.iso12:piece lengthi262144e6:pieces32480:[每個部分的hash,以二進位制表示] ``` 之後的內容為二進位制,無法直接檢視。 美化一下這個部分的資訊,可以發現清晰的結構特徵: ```json d 8:announce 41:http://bttracker.debian.org:6969/announce 7:comment 35:"Debian CD from cdimage.debian.org" 13:creation date i1612616380e 9:httpseeds l 146:https://cdimage.debian.org/cdimage/release/edu//srv/cdbuilder.debian.org/dst/deb-cd/weekly-builds/amd64/iso-cd/debian-edu-10.8.0-amd64-netinst.iso 146:https://cdimage.debian.org/cdimage/archive/edu//srv/cdbuilder.debian.org/dst/deb-cd/weekly-builds/amd64/iso-cd/debian-edu-10.8.0-amd64-netinst.iso e 4:info d 6:length i425721856e 4:name 35:debian-edu-10.8.0-amd64-netinst.iso 12:piece length i262144e 6:pieces 32480:[每個部分的hash,以二進位制表示] e e ``` 其中包含了tracker伺服器的URL、建立事件(Unix時間戳)、檔名和檔案大小、以及一系列表示每個檔案塊的**SHA\-1**雜湊值的二進位制片段(檔案塊是指檔案被等量拆分後形成的幾個部分)。每個種子中檔案被拆分的大小依據是不同的,但基本處在**一個區間內(256KB到1MB)**。因為這樣的設計,大型檔案將會被拆分成眾多碎片。在實際下載中,下載執行者會從能夠連線的那些peers主機下載檔案塊,並且根據種子檔案校驗其雜湊值,最後拼接成完整的檔案。 這種機制能夠確保每個檔案塊的完整性,抵禦裝置故障或惡意投毒(torrent poisoning)造成的損害。如果攻擊者不能破解SHA\-1進行[原像攻擊](https://zh.wikipedia.org/wiki/原像攻擊)(preimage attack),那麼下載取得的檔案就是安全可靠的。 ### Bencode編碼 從已知的資訊可以看出,\.torrent檔案中的元資料均以“鍵:值”形式儲存,故可以將整個內容理解為一個經過特殊編碼的字典,或者一個近似的JSON。 Bencode中,數字採用十進位制編碼,相比純二進位制編碼顯得效率較低,但保證了良好的跨平臺性(無大小端儲存問題)。 Bencode支援四種類型的資料:string、int、Dictionary\、List\。 - **string型別** string型別的編碼格式為**\[length\]:\[string\]**,以字串長度開頭,以字串內容結束。示例: ``` "abc" => 3:abc ``` - **int型別** int型別的編碼格式為**i\[int\]e**,以i開頭,以e結尾。示例: ``` 123 => i123e ``` - **Dictionary\型別** Dictionary\型別的編碼格式為**d\[Key\-Value Pair\]e**,以d開頭,以e結尾。示例: ``` Dictionary<{"name":"create chen"},{"age":23}> => d4:name11:create chen3:agei23ee ``` - **List\型別** List\型別的編碼格式為**l\[object\]e**,以l開頭,以e結尾。示例: ``` List<"abc", 123> => l3:abci123ee ``` ### Bencode實現 #### 編碼 ```java public static string Encode(object obj) { var sb = new StringBuilder(); if(obj is Dictionary) { var parseObj = obj as Dictionary; sb.Append("d"); foreach (var o in parseObj) { sb.AppendFormat("{0}:{1}{2}", o.Key.Length,o.Key, Encode(o.Value)); } sb.Append("e"); } if ((obj as int?) != null) { var parseObj = (int) obj; sb.AppendFormat("i{0}e", parseObj); } if (obj is List) { var parseObj = obj as List; sb.Append("l"); foreach (var o in parseObj) { sb.Append(Encode(o)); } sb.Append("e"); } if (obj is string) { var parseObj = obj as string; sb.AppendFormat("{0}:{1}", parseObj.Length, parseObj); } return sb.ToString(); } ``` #### 解碼 ```java public static object Decode(string s) { return DecodeObject(s, ref _index, EncodeState.Value); } private enum EncodeState { Key, Value } private static int _index; private static object DecodeObject(string str,ref int index, EncodeState state) { var obj = new Dictionary(); var c = str[index]; while (c != 'e') { if (c == 'd') { index++; return DecodeObject(str, ref index,EncodeState.Key); } if (c == 'i') { var value = ""; index++; c = str[index]; while (c != 'e') { value += c.ToString(CultureInfo.InvariantCulture); index++; c = str[index]; } return Convert.ToInt32(value); } if (c == 'l') { index++; var value = new List(); while (str[index]!='e') { value.Add(DecodeObject(str, ref index, EncodeState.Value)); index++; } return value; } if ('0' < c && c <= '9') { string strLength = ""; while (c != ':') { strLength += c.ToString(CultureInfo.InvariantCulture); c = str[++index]; } var length = Convert.ToInt32(strLength); var strContent = ""; for (int i = 0; i < length; i++) { strContent += str[index + 1].ToString(CultureInfo.InvariantCulture); index++; } if (state == EncodeState.Value) { return strContent; } index++; obj.Add(strContent, DecodeObject(str, ref index, EncodeState.Value)); state = EncodeState.Key; index++; } c = str[index]; } return obj; } ``` ## 編寫專案 這裡使用Go來編寫,也是首次使用Go完成網路工具。僅包含主要程式碼,完整專案見[Github](https://github.com/4thrun/Tiny-BT-Client)。 ### 尋找 #### 解析種子(\~/torrentfile/torrentfile\.go) ```go import ( "github.com/jackpal/bencode-go" ) ``` 這裡省略了自帶庫檔案的匯入。 ```go type bencodeInfo struct { Pieces string `bencode:"pieces"` PieceLength int `bencode:"piece length"` Length int `bencode:"length"` Name string `bencode:"name"` } type bencodeTorrent struct { Announce string `bencode:"announce"` Info bencodeInfo `bencode:"info"` } ``` ```go // Open函式用於解析種子 func Open(path string) (TorrentFile, error) { file, err := os.Open(path) if err != nil { return TorrentFile{}, err } defer file.Close() bto := bencodeTorrent{} err = bencode.Unmarshal(file, &bto) if err != nil { return TorrentFile{}, err } return bto.toTorrentFile() } ``` 處理時,將**pieces**對應的值(原先為雜湊值的字串)變成雜湊值切片(每個長度為20 bytes),以便後續呼叫每個獨立的雜湊值。另外,計算**info**對應的整個字典(含有名稱、大小、檔案塊雜湊值)的SHA\-1雜湊值,儲存在**infohash**,在與trackers伺服器和peers主機互動時表示所需的檔案。 ```go type TorrentFile struct { Announce string InfoHash [20]byte PieceHashes [][20]byte PieceLength int Length int Name string } ``` ```go func (bto bencodeTorrent) toTorrentFile() (TorrentFile, error) { // ... } ``` #### 從trackers伺服器獲取peers主機地址(\~/torrentfile/tracker\.go) 處理完種子後,就可以向trackers伺服器發起請求:作為一臺peer主機,需要獲取同一網路中的其它peers主機的列表。只需要對**announce**對應URL發起GET請求(需要設定幾個請求引數)。 ```go // buildTrackerURL函式用於構成請求peers列表的序列 func (t * TorrentFile) buildTrackerURL(peerID [20]byte, port uint16) (string, error) { base, err:= url.Parse(t.Announce) if err != nil { return "", err } params := url.Values{ "info_hash": []string{string(t.InfoHash[:])}, "peer_id": []string{string(peerID[:])}, "port": []string{strconv.Itoa(int(port))}, "uploaded": []string{"0"}, "downloaded": []string{"0"}, "compact": []string{"1"}, "left": []string{strconv.Itoa(t.Length)}, } base.RawQuery = params.Encode() return base.String(), nil } ``` 其中重要的引數有: - **info\_hash**:用以標識需要下載的檔案,其值就是之前由**info**對應值計算出的**infohash**。trackers伺服器基於這個值返回能夠為下載提供資源的peers主機。 - **peer\_id**:20位元組長的資料,用於向peers主機和trackers伺服器標識自己的身份。具體實現僅僅是產生隨機的20個位元組。真實的BitTorrent客戶端ID形如`-TR2940-k8hj0wgej6ch`,標出了客戶端軟體及其版本(`TR2940`表示Transmission Client 2.94)。 #### 處理trackers伺服器的響應(\~/peers/peers\.go) 伺服器響應也是採用Bencode編碼的: ```json d 8:interval i900e 5:peers 252:[很長的二進位制塊] e ``` `interval`表示本地應當在多長的時間間隔後再次向tracker伺服器請求以重新整理peers主機列表,900的單位是秒。`peers`包含了每個peer主機的IP地址,以二進位制表示,由若干個**6位元組元**組成,前4個位元組表示主機IP,後2個位元組表示埠號(大端儲存的16位無符號整型,uint16)。大端儲存,即**big\-endian**,是網路中所採用的儲存方式(相對於小端儲存),故被稱為**network order**。運算時可以直接將一組位元組從左至右拼接以形成所要表達的整數,如`0x1A`和`0xE1`能拼接成`0x1AE1`,即十進位制的6881。 ```go type Peer struct { IP net.IP Port uint16 } ``` ```go // Unmarshal函式從緩衝區解析IP及其埠 func Unmarshal(peerBin []byte)([]Peer, error) { const peerSize = 6 numPeers := len(peerBin) / peerSize if len(peerBin) % peerSize != 0 { err := fmt.Errorf("received malformed peers") return nil, err } peers := make([]Peer, numPeers) for i := 0; i < numPeers ; i++ { offset := i * peerSize peers[i].IP = net.IP(peerBin[offset : offset+4]) peers[i].Port = binary.BigEndian.Uint16(peersBin[offset+4 : offset+6]) } return peers, nil } ``` ### 下載 在取得peers主機的地址後,就可以進行下載了。對每臺peer主機的連線,有如下的幾個步驟: 1. 與目標peer建立TCP連線; 2. 完成BitTorrent握手; 3. 交換資訊(告知對方本地需要的資源)。 #### TCP連線(\~/client/client\.go) 設定一個超時檢測機制,防止消耗過多網路資源。 ```go conn, err := net.DialTimeout("tcp", peer.String(), 3*time.Second) if err != nil { return nil, err } ``` #### 握手(\~/handshake/handshake\.go) 通過達成握手,以確定某peer主機具有期望的功能: - 能夠使用BT協議通訊; - 能夠理解本機發出的資訊,並作出響應; - 持有本機需要的檔案資源,或者持有檔案資源在網路中位置的索引。 BitTorrent握手行為需要傳輸的資訊由5個部分構成: 1. 協議標識(表明這是BitTorrent協議)的長度,即19,十六進位制表示為`0x13`; 2. 協議標識,被稱為**pstr**,即`BitTorrent protocol`; 3. 8個保留位元組,預設全為0,如果客戶端支援BT協議的某些擴充套件,則需要將其中一些設定為1; 4. **infohash**,基於種子中**info**對應的全部資訊計算得出的雜湊值,用於標明本機需要的檔案; 5. **PEER ID**,用於標明本機身份。 這些資訊組合起來,就是達成握手需要的序列: ``` \x13BitTorrent protocol\x00\x00\x00\x00\x00\x00\x00\x00\x86\xd4\xc8\x00\x24\xa4\x69\xbe\x4c\x50\xbc\x5a\x10\x2c\xf7\x17\x80\x31\x00\x74-TR2940-k8hj0wgej6ch ``` 本機發出這些資訊後,peers主機應當以相同形式響應,且返回的**infohash**應當與本機持有的一致。 使用一個結構體表示握手包,並新增一些序列化、讀取函式。 ```go // 握手包結構體 type Handshake struct { Pstr string InfoHash [20]byte PeerID [20]byte } ``` ```go //Serialize函式用於序列化握手資訊 func (h *Handshake) Serialize() []byte { buf := make([]byte, len(h.Pstr)+49) buf[0] = byte(len(h.Pstr)) curr := 1 curr += copy(buf[curr:], h.Pstr) curr += copy(buf[curr:], make([]byte, 8)) //即8個保留位元組 curr += copy(buf[curr:], h.InfoHash[:]) curr += copy(buf[curr:], h.PeerID[:]) return buf } func Read(r io.Reader) (* Handshake, error) { // ... } ``` #### 資訊 完成握手後就將開始正式的收發資訊。如果遠端的peers主機未能做好收發的準備,本機仍舊無法傳送資訊,此時本機會被遠端認定為**阻塞的(choked)**。在peers主機完成準備後,會向本機發送**解除阻塞(unchoke)**資訊。程式碼設計中,預設需要傑出阻塞才能進行下載。 ##### 解析(\~/message/message\.go) 資訊包含三個部分:長度、ID、payload。 長度為32位整型,是大端儲存形式的4個位元組。ID用以表示資訊型別,這在程式碼中進行了詳細定義。 ```go type messageID uint8 const ( // MsgChoke表示阻塞 MsgChoke messageID = 0 // MsgUnchoke表示解除阻塞 MsgUnchoke messageID = 1 // MsgInterested表示資訊相關 MsgInterested messageID = 2 // MsgNotInterested表示資訊不相關 MsgNotInterested messageID = 3 // MsgHave表示提醒接收者,傳送者擁有資源 MsgHave messageID = 4 // MsgBitfield表示傳送者擁有資源的哪些部分 MsgBitfield messageID = 5 // MsgRequest表示向接收方請求資料 MsgRequest messageID = 6 // MsgPiece表示傳送資料以完成請求 MsgPiece messageID = 7 // MsgCancel表示取消一個請求 MsgCancel messageID = 8 ) //Message結構體儲存ID和包含資訊的payload type Message struct { ID messageID Payload []byte } ``` ```go // Serialize函式用於執行序列化 // 資訊依次為字首、資訊的ID、payload // 需要將`nil`解釋為`keep-alive` func (m *Message) Serialize() []byte { if m == nil { return make([]byte, 4) } length := uint32(len(m.Payload) + 1) buf := make([]byte, 4+length) binary.BigEndian.PutUint32(buf[0:4], length) buf[4] = byte(m.ID) copy(buf[5:], m.Payload) return buf } ``` 為讀取資訊,也需要依照資訊格式編寫函式。先讀取4個位元組並作為一個`uint32`以表示長度**length**,然後依據這個數字讀取相應位數的資料,這部分中的第一個位元組表示**ID**,剩下的表示**payload**。 ```go // Read函式用於解析資訊 func Read(r io.Reader) (*Message, error) { lengthBuf := make([]byte, 4) _, err := io.ReadFull(r, lengthBuf) if err != nil { return nil, err } length := binary.BigEndian.Uint32(lengthBuf) // keep-alive if length == 0 { return nil, nil } messageBuf := make([]byte, length) _, err = io.ReadFull(r, messageBuf) if err != nil { return nil, err } m := Message{ ID: messageID(messageBuf[0]), Payload: messageBuf[1:], } return &m, nil } ``` ##### 位域(\~/bitfield/bitfield\.go) peers主機使用位域來高效地編碼自身能夠提供的資源分塊。位域類似基於位元組的陣列,被標為1的位即代表擁有這個資源分塊。因為使用單個的位即能完成標註,位域有極高的壓縮能力,這意味著在一個布林(`bool`)空間內完成了8次布林型別的操作。 當然這樣的思路需要一定的代價:可以定址的最小記憶體單位是位元組,處理單個的位就需要額外的函式設計。 ```go // Bitfield用以表示一臺peer主機擁有的資源分塊 type Bitfield []byte ``` ```go // HasPiece用以表明一個位域(bitfield)是否有特定的索引集 func (bf Bitfield) HasPiece(index int) bool { byteIndex := index / 8 offset := index % 8 if byteIndex < 0 || byteIndex >= len(bf) { return false } return bf[byteIndex] >> uint(7-offset)&1 != 0 } // SetPiece用以在位域設定單個位 func (bf Bitfield) SetPiece(index int) { byteIndex := index / 8 offset := index % 8 // 撇除不合規的索引 if byteIndex < 0 || byteIndex >= len(bf) { return } bf[byteIndex] |= 1 << uint(7-offset) } ``` ### 組裝 至此完成了所有下載種子檔案的工具: - 從trackers伺服器獲得了peers主機列表; - 與peers主機達成TCP連線; - 與peers主機進行握手; - 與peers主機收發資訊。 現在面臨的問題是如何解決下載必然造成的**高併發(concurrency)**,並且需要統一管理每個連線的peer主機的**狀態(state)**。 #### 高併發(\~/p2p/p2p\.go) 在*Effective Go*中對併發的描述中有這樣一句話: >
Do not communicate by sharing memory; instead, share memory by communicating. [官網](https://golang.org/ref/mem)給出瞭解釋。 這裡將Go中重要的Channel型別作為簡潔且執行緒安全的佇列。Channel可以被認為是管道,通過併發核心單元就可以傳送或者接收資料進行通訊(communication)。 建立兩個Channel來同步併發工作:一個用於在peers主機間分派工作(要下載的資源分塊),另一個用於已下載的分塊。 ```go workQueue := make(chan *pieceWork, len(t.PieceHashes)) results := make(chan *pieceResult) for index, hash := range t.PieceHashes { length := t.calculatePieceSize(index) workQueue <- &pieceWork{index, hash, length} } // 執行下載 for _, peer := range t.Peers { go t.startDownloadWorker(peer, workQueue, results) } // 收集分塊 buf := make([]byte, t.Length) donePieces := 0 for donePieces < len(t.PieceHashes) { res := <- results begin, end := t.calculateBoundsForPiece(res.index) copy(buf[begin:end], res.buf) donePieces ++ percent := float64(donePieces) / float64(len(t.PieceHashes)) * 100 numWorkers := runtime.NumGoroutine() - 1 log.Printf("(%0.2f%%) downloaded piece #%d from %d peers\n", percent, res.index, numWorkers) } close(workQueue) ``` 為取得的每個peer主機都生成一個**goroutine(輕量級執行緒)**。每個執行緒連線peer主機並握手,然後從`workQueue`中抽取任務,嘗試進行下載,並把下載得到的分塊傳至名為`results`的**channel**。 可以用流程圖表示這個過程: ![image](data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAeAB4AAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAOpAtADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9U6KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoooo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P6+ZxLCpNu+585+H9J0CPw34wttNtbLwnrE+mvHYpFpgs5LrT1UGS4iQqvzTAAOVyybYd33UFVdN0/we2s6c154HumghnguZNRtfB160twFtiHSSZLbMwM+yTduYPzkkY3fS9FY/Xnro9fP/AIBf1fb/AC/4J8j/ABt+HcX/AAkt5Ne+DrGxh1XV2uba7062juLq7ZlSLynUmJd0hSWbarzPiVyYsh2XvdHGkJ8HZNHt9LgtPFMt68Vvpum6fHaNaaxsEiiNYlUAQblBnIwUjLElWGfe6KcsfKdOMJL4fMFhlGTknuFFFFeUdgUUUUAFFFFAHE/EY/btT8GaSvzPda1HcOvpHbxvOWPsHjjH1YV21cPprDxJ8VtQvk+ey8P2X9mI/wDCbqdklnA91RLcZ9XYetdxW9T3VGHZfnr+VjOGrbCiiisDQKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAOV+Inh281rSba80lYzr2k3C31h5jbFkcAq8LN2WSNnQntuB7Vb8LeI7PxdolvqdiWEUm5XikG2SGRSVeJ1/hdWBUjsQa364fXdFv8Awnq914j8P27XsFywk1bRY8brggAfaIM8CYKACp4kCgcMAT0waqR9m9+n+X+X/BMZJxfMvmdgFp4Ws3w54j0zxZpceo6RexX1o5K74zyrD7yMDyrA8FSAQeCBWrtrGScXZ7lqzV0IFp22loqSwooopAFFFFABRRRQAUUUUAFFFFABXO+NvFn/AAiulxm3hF7rF7ILXTbDdtNzcMCVXPZQAWZv4VVj2qbxX4y0zwdZxTX8rNPcP5VpZQDfcXcvaOJOrN+gHJIAJrN8MeG7+51X/hJfEYjOtPG0VrZRNvh02FiCY0b+ORsLvk77QFwo53hFJe0nt+f9df8AMzlJv3Y7/kaHgjwz/wAIj4atNPeb7Vd/NNd3WMG4uJGLyyH/AHnZjjsMDtW9RRWUpOTcnuy0lFWQUUUVIwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAOT174e299qjazo93J4d8QMAGv7RQUuAP4Z4j8so7ZPzD+FlqmviTxloPyav4Xj1yIf8AL74duEBYerW87IU+iySV3FFbqq7Wmr+v+e/6GfIr3i7HE/8AC2NMj4udH8UWr91/4Ru+mx+MUTj9aX/hbuh/8+Hij/wk9V/+Rq7Wijmpfyv7/wDgBaff8P8AgnFf8Ld0P/nw8Uf+Enqv/wAjUf8AC3dD/wCfDxR/4Seq/wDyNXa0Uc1H+V/ev8gtPuvu/wCCcV/wt3Q/+fDxR/4Seq//ACNUS/Gjw293JarB4ia6jRZZIB4W1QyIjFgrFfs+QGKOATwSjY6Gu6rjtL/5K94m/wCwFpX/AKUajWsFRkpPlei7rul28yJOomlda+Xl6kf/AAt3Q/8Anw8Uf+Enqv8A8jUf8Ld0P/nw8Uf+Enqv/wAjV2tFZc1H+V/ev8i7T7r7v+CcV/wt3Q/+fDxR/wCEnqv/AMjUf8Ld0P8A58PFH/hJ6r/8jV2tFHNR/lf3r/ILT7r7v+CcT/wtaxm4stC8UXr9k/sC7t8/jOkaj8SKa2reOPEXyWGi2nhS1brd6zMt1cgf7NvCxTPu03HHynpXcUUe0hH4Y/fr/kvwDlk92c14Y8B2Hhy6l1GSSbVtdnXbcavfkPO4/urgBY0/2ECr7Z5rpaKKzlKU3eTLUVFWQUUUVAwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArjtL/AOSveJv+wFpX/pRqNdjXHaX/AMle8Tf9gLSv/SjUa6KXwVPT/wBuRlP4o+v6M7Giiiuc1CiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArjtL/AOSveJv+wFpX/pRqNdjXHaX/AMle8Tf9gLSv/SjUa6KXwVPT/wBuRlP4o+v6M7Giiiuc1CiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArjtL/AOSveJv+wFpX/pRqNdjXHaX/AMle8Tf9gLSv/SjUa6KXwVPT/wBuRlP4o+v6M7Giiiuc1CiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArjtL/AOSveJv+wFpX/pRqNdjXifhn40eH9W/aE17QIEv/AO0prK100RvbEBZbaW9eYsc8LtlQhuhzxXbh6U6kKrgr2jr96OerOMZQ5na7/RntlFFFcR0BRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB5xe/ETxNN4n8QaZovhvSby10i7js2ub7WpbZ5Ha2hnJEa2sgAAnC/e52ngUv/CZePv+hT8Of+FJcf8AyBVXw2u7xt8Rv+w5D/6a7CuoWOvSkqcbLkWy79l5nNHmld83V9u/oYf/AAl/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