最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

DHT 協(xié)議具體是什么呢?

2023-06-20 16:50 作者:IMFile  | 我要投稿

DHT(Distributed Hash Table)分布式哈希表?是分布式計(jì)算系統(tǒng)中的一個(gè)類別,是一種分布式系統(tǒng),提供類似于哈希表的查找服務(wù)。鍵值對存儲在?DHT?分布式哈希表?中,任何參與的節(jié)點(diǎn)都可以有效地檢索與給定關(guān)聯(lián)的鍵值。在?BitTorrent 與 Magnet 的原理與對比?一文中,我們已經(jīng)介紹了他們的聯(lián)系和區(qū)別,現(xiàn)在我們將單獨(dú)詳細(xì)的說明一下,DHT 協(xié)議具體是什么。


DHT 的主要優(yōu)點(diǎn)是可以添加或刪除節(jié)點(diǎn),只需最少量的重新分發(fā)密鑰工作。鍵值是映射到特定值的唯一標(biāo)識符,而特定值又可以是從地址到文檔到任意數(shù)據(jù)的任何內(nèi)容。 維護(hù)從鍵值到數(shù)值的映射的責(zé)任分布在節(jié)點(diǎn)之間,對所涉及的參與者的任何更改對系統(tǒng)或過程的整體功能產(chǎn)生影響降低到最小程度。這允許 DHT 擴(kuò)展到非常大量的節(jié)點(diǎn),并處理持續(xù)的節(jié)點(diǎn)到達(dá)、離開和故障。

BitTorrent 使用 “分布式松散哈希表”(DHT)來存儲基于 Trackerless 協(xié)議的種子節(jié)點(diǎn)聯(lián)系信息。實(shí)際上,每個(gè)節(jié)點(diǎn)都變成了一個(gè) Tracker 。該協(xié)議基于 Kademila,并通過 UDP 實(shí)現(xiàn)。

請注意本文檔中使用的術(shù)語,以避免混淆。 Peer 節(jié)點(diǎn)是在實(shí)現(xiàn) BitTorrent 協(xié)議的 TCP 端口上偵聽的客戶端/服務(wù)器。 Node 節(jié)點(diǎn)是偵聽實(shí)現(xiàn)分布式哈希表協(xié)議的 UDP 端口的 Tracker 客戶端/服務(wù)器。 DHT 由 Node 節(jié)點(diǎn)和存儲 Peer 的位置節(jié)點(diǎn)組成。 BitTorrent 客戶端包括一個(gè) DHT 節(jié)點(diǎn),該節(jié)點(diǎn)用于聯(lián)系 DHT 中的其他 Node 節(jié)點(diǎn),以獲取使用 BitTorrent 協(xié)議下載的 Peer 節(jié)點(diǎn)的位置。

Peer 通常是指參與文件共享的用戶端,也就是下載或上傳特定文件的客戶端程序,它們通常都是位于同一層級的。每個(gè) peer 都可以下載和上傳文件,這使得整個(gè)網(wǎng)絡(luò)更加去中心化,因?yàn)闆]有任何一個(gè)節(jié)點(diǎn)掌握了所有的數(shù)據(jù)。

Node 則通常指的是 Tracker 服務(wù)器,也就是通過 Tracker 協(xié)議來管理和協(xié)調(diào)各個(gè) Peer 之間的連接和數(shù)據(jù)傳輸。 Tracker 服務(wù)器會維護(hù)一份記錄活躍 Peer 的列表,并將其發(fā)送給其他 Peer,以幫助它們建立連接并找到其他可以共享文件的 Peer 。

因此,在 BitTorrent 中,Peer 是指下載和上傳文件的客戶端程序,而 Node 則指的是 Tracker 服務(wù)器,用于協(xié)調(diào) Peer 之間的連接和文件共享。

概述

每個(gè) Node 節(jié)點(diǎn)都有一個(gè)全局唯一標(biāo)識符,稱為 Node ID 。 Node ID 是從與 BitTorrent 信息哈希相同的 160 Bit 空間中隨機(jī)選擇的。距離指標(biāo)用于比較兩個(gè) Node ID ,或 Node ID 和接近度比較的信息哈希。 Node 節(jié)點(diǎn)必須維護(hù)一個(gè)路由表,其中包含少量其他節(jié)點(diǎn)的聯(lián)系信息。隨著 ID 越來越接近節(jié)點(diǎn)自己的 ID,路由表變得更加詳細(xì)。節(jié)點(diǎn)知道 DHT 中的許多其他節(jié)點(diǎn),這些節(jié)點(diǎn)的 ID 與自己的 ID 接近,但只有少數(shù)下載方的 ID 離自己的 ID 很遠(yuǎn)。

在 Kademlia 中,距離度量是 XOR,結(jié)果被解釋為無符號整數(shù)。?distance(A,B) = |A xor B|? 值越小越近。

當(dāng) Node 節(jié)點(diǎn)想要查找種子的 Peer 節(jié)點(diǎn)時(shí),它會使用距離指標(biāo)將種子的信息哈希與其自己的路由表中節(jié)點(diǎn)的 ID 進(jìn)行比較。然后,它使用最接近信息哈希的 ID 聯(lián)系它所知道的節(jié)點(diǎn),并要求他們提供當(dāng)前下載種子的 Peer 節(jié)點(diǎn)的下載信息。如果聯(lián)系的節(jié)點(diǎn)知道種子的對等節(jié)點(diǎn),則對等節(jié)點(diǎn)聯(lián)系信息將隨響應(yīng)一起返回。否則,聯(lián)系的節(jié)點(diǎn)必須使用其路由表中最接近種子信息哈希的節(jié)點(diǎn)的聯(lián)系信息進(jìn)行響應(yīng)。原始節(jié)點(diǎn)迭代查詢更接近目標(biāo)信息哈希的節(jié)點(diǎn),直到找不到任何更近的節(jié)點(diǎn)。搜索完畢后,客戶端將自身的對等下載方信息插入到具有最接近種子信息哈希的 ID 的響應(yīng)節(jié)點(diǎn)上。

infohash 是一個(gè)由 40 個(gè)十六進(jìn)制字符表示的唯一標(biāo)識符,用于標(biāo)識一個(gè) torrent 文件。這個(gè)標(biāo)識符是通過將 torrent 文件的元數(shù)據(jù)哈希生成的,它包括了文件名、文件大小、文件數(shù)量等信息。

當(dāng)一個(gè)客戶端想要下載一個(gè) torrent 文件時(shí),它會向 tracker 發(fā)送包含該文件 infohash 的請求。 Tracker 將回復(fù)一個(gè)包含可用種子和對等方的列表,該列表可以幫助客戶端連接到其他客戶端并開始下載文件。

因?yàn)?infohash 是根據(jù)文件的內(nèi)容生成的,所以即使兩個(gè) torrent 文件的名稱不同,只要它們包含相同的數(shù)據(jù),那么它們的 infohash 就會相同。

Peer 節(jié)點(diǎn)查詢的返回值包括一個(gè)稱為 token 的不透明值。要使 Node 節(jié)點(diǎn)宣布其控制 Peer 節(jié)點(diǎn)正在下載種子,它必須在最近的 Peer 節(jié)點(diǎn)查詢中提供從同一查詢節(jié)點(diǎn)收到的 Token 。當(dāng)節(jié)點(diǎn)嘗試發(fā)行種子時(shí),被查詢的節(jié)點(diǎn)會根據(jù)查詢節(jié)點(diǎn)的 IP 地址檢查 Token 。由于 Token 僅由查詢節(jié)點(diǎn)返回到它從中接收 Token 的同一節(jié)點(diǎn),Token 必須在分發(fā)后的合理時(shí)間內(nèi)被接受。 BitTorrent 實(shí)現(xiàn)使用 IP 地址的 SHA1 哈希連接到一個(gè) Token 上,該 Token 每五分鐘更改一次,并接受長達(dá) 10 分鐘的 Token 。

在 BitTorrent 中,”Token” 通常指的是一種通過 Tracker 服務(wù)器授權(quán)的方式,用于幫助客戶端獲取其他對等方(Peers)和下載所需文件塊的一次性密鑰或令牌。

當(dāng)一個(gè) BitTorrent 客戶端想要加入一個(gè)特定的 Torrent 下載時(shí),它首先會向 Tracker 發(fā)送請求,以獲取可用的對等方列表。 如果 Tracker 需要進(jìn)行身份驗(yàn)證,它可能會返回一個(gè) “Token” 給客戶端,作為一次性令牌,該令牌只能用于這個(gè)特定的 Torrent 下載。

客戶端可以使用這個(gè) Token 向 Tracker 發(fā)送更多的請求,包括更新對等方列表和下載文件塊的請求。 這個(gè) Token 可以防止未經(jīng)許可的客戶端或?qū)Φ确皆噲D加入下載,并且增強(qiáng)了整個(gè) BitTorrent 網(wǎng)絡(luò)的安全性。

路由表

每個(gè)節(jié)點(diǎn)都維護(hù)一個(gè)已知良好節(jié)點(diǎn)的路由表。路由表中的節(jié)點(diǎn)用作 DHT 中查詢的起點(diǎn)。返回路由表中的節(jié)點(diǎn)以響應(yīng)來自其他節(jié)點(diǎn)的查詢。

并非我們了解的所有節(jié)點(diǎn)都是平等的。有些是好的,有些則不是。許多使用 DHT 的節(jié)點(diǎn)能夠發(fā)送查詢和接收響應(yīng),但無法響應(yīng)來自其他節(jié)點(diǎn)的查詢。重要的是,每個(gè)節(jié)點(diǎn)的路由表必須僅包含已知良好的節(jié)點(diǎn)。一個(gè)好的節(jié)點(diǎn)是在過去 15 分鐘內(nèi)響應(yīng)了我們的一個(gè)查詢的節(jié)點(diǎn)。如果一個(gè)節(jié)點(diǎn)曾經(jīng)響應(yīng)過我們的一個(gè)查詢,并且在過去 15 分鐘內(nèi)向我們發(fā)送了一個(gè)查詢,那么它也很好。處于非活動狀態(tài) 15 分鐘后,節(jié)點(diǎn)變得有問題。當(dāng)節(jié)點(diǎn)無法連續(xù)響應(yīng)多個(gè)查詢時(shí),它們會變得糟糕。我們知道良好的節(jié)點(diǎn)優(yōu)先于狀態(tài)未知的節(jié)點(diǎn)。

路由表覆蓋從 0 到 2160? 的整個(gè)節(jié)點(diǎn) ID 空間。路由表細(xì)分為 buckets,每個(gè) buckets 覆蓋一部分空間??毡碛幸粋€(gè) bucket,其 ID 空間范圍為 min=0, max=2160?。當(dāng) ID 為 “N” 的節(jié)點(diǎn)插入表中時(shí),該節(jié)點(diǎn)將放置在最小值為 <= N < 最大值的存儲桶中。空表只有一個(gè) bucket,因此任何節(jié)點(diǎn)都必須適合其中。每個(gè) bucket 只能容納 K 個(gè)節(jié)點(diǎn),目前是 8 個(gè)節(jié)點(diǎn),然后才能算 “裝滿” 。當(dāng) bucket 充滿已知良好的節(jié)點(diǎn)時(shí),除非我們自己的節(jié)點(diǎn) ID 在存儲桶的范圍內(nèi),否則不能再添加節(jié)點(diǎn)。在這種情況下,bucket 將替換為兩個(gè)新 buckets,每個(gè) bucket 的范圍是舊 bucket 的一半,并且舊 bucket 中的節(jié)點(diǎn)分布在兩個(gè)新 bucket 之間。對于只有一個(gè) bucket 的新表,整個(gè) bucket 始終拆分為兩個(gè)新 buckets,范圍為 0..2159??和?2159..2160?。

在 BitTorrent 協(xié)議中,Bucket 是指下載器在下載文件時(shí),將下載任務(wù)分成多個(gè)子任務(wù),并將每個(gè)子任務(wù)分配給不同的遠(yuǎn)程上傳者(peers)來下載的數(shù)據(jù)塊。這些數(shù)據(jù)塊被組織成 Bucket,可以看作是一組數(shù)據(jù)塊的集合。

通常情況下,一個(gè) Bucket 包含數(shù)百個(gè)數(shù)據(jù)塊,每個(gè)數(shù)據(jù)塊的大小為 16KB 到 64KB 左右。下載器會嘗試從多個(gè)上傳者處獲取不同的 Bucket,以便加速下載。這種方式也被稱為多點(diǎn)下載(multi-source downloading),因?yàn)橄螺d者從多個(gè)源同時(shí)下載數(shù)據(jù)。

當(dāng) bucket 中裝滿了良好節(jié)點(diǎn)時(shí),新節(jié)點(diǎn)將被簡單地丟棄。如果已知 bucket 中的任何節(jié)點(diǎn)已損壞,則一個(gè)節(jié)點(diǎn)將替換為新節(jié)點(diǎn)。如果 bucket 中有任何可疑節(jié)點(diǎn)在過去 15 分鐘內(nèi)未被查詢到,則會對最近最少查詢的節(jié)點(diǎn)執(zhí)行 ping 操作。如果 ping 的節(jié)點(diǎn)響應(yīng),則對下一個(gè)最近最少查詢的可疑節(jié)點(diǎn)進(jìn)行 ping 操作,直到一個(gè)節(jié)點(diǎn)無法響應(yīng)或 bucket 中的所有節(jié)點(diǎn)都已知良好。如果 bucket 中的節(jié)點(diǎn)無法響應(yīng) ping,建議在丟棄該節(jié)點(diǎn)并將其替換為新的良好節(jié)點(diǎn)之前再試一次。這樣,表中就會填充穩(wěn)定的長時(shí)間運(yùn)行的節(jié)點(diǎn)。

每個(gè) bucket 都應(yīng)維護(hù)一個(gè) “上次更改” 屬性,以指示內(nèi)容的 “新鮮” 程度。當(dāng) bucket 中的節(jié)點(diǎn)被 ping 并響應(yīng)時(shí),或者將節(jié)點(diǎn)添加到 bucket ,或者 bucket 中的節(jié)點(diǎn)替換為另一個(gè)節(jié)點(diǎn)時(shí),應(yīng)更新 bucket 的上次更改屬性。 15 分鐘內(nèi)未更改的 bucket 應(yīng) “刷新” 。這是通過在 bucket 范圍內(nèi)選擇一個(gè)隨機(jī) ID 并對其執(zhí)行 find_nodes 搜索來完成的。能夠接收來自其他節(jié)點(diǎn)的查詢的節(jié)點(diǎn)通常不需要經(jīng)常刷新 bucket 。無法從其他節(jié)點(diǎn)接收查詢的節(jié)點(diǎn)通常需要定期刷新所有 bucket ,以確保在需要 DHT 時(shí)其表中有良好的節(jié)點(diǎn)。

將第一個(gè)節(jié)點(diǎn)插入其路由表后以及此后啟動時(shí),節(jié)點(diǎn)應(yīng)嘗試在 DHT 中查找與自身最近的節(jié)點(diǎn)。它通過向越來越近的節(jié)點(diǎn)發(fā)出 find_node 消息來實(shí)現(xiàn)這一點(diǎn),直到它找不到更近的節(jié)點(diǎn)。路由表應(yīng)在客戶端軟件的調(diào)用之間保存。

BitTorrent 協(xié)議擴(kuò)展

BitTorrent 協(xié)議已擴(kuò)展到在 Tracker 引入的 Peer 節(jié)點(diǎn)之間交換節(jié)點(diǎn) UDP 端口號。通過這種方式,客戶端可以通過下載常規(guī)種子來自動做種他們的路由表。在第一次嘗試下載 trackerless 種子的新安裝客戶端的路由表中將沒有任何節(jié)點(diǎn),種子文件中也需要節(jié)點(diǎn)信息。

支持 DHT 的 Peer 節(jié)點(diǎn)設(shè)置在 BitTorrent 協(xié)議握手中交換的 8 字節(jié)保留標(biāo)志的最后一位。 Peer 節(jié)點(diǎn)收到指示遠(yuǎn)程 Peer 節(jié)點(diǎn)支持 DHT 的握手時(shí),應(yīng)發(fā)送 PORT 消息。它以字節(jié) 0x09 開頭,并具有兩個(gè)字節(jié)的有效負(fù)載,其中包含按網(wǎng)絡(luò)字節(jié)順序排列的 DHT 節(jié)點(diǎn)的 UDP 端口。收到此消息的 Peer 節(jié)點(diǎn)應(yīng)嘗試在遠(yuǎn)程 Peer 節(jié)點(diǎn)的接收端口和 IP 地址上 ping 節(jié)點(diǎn)。如果收到對 ping 的響應(yīng),節(jié)點(diǎn)應(yīng)嘗試根據(jù)常規(guī)規(guī)則將新的聯(lián)系信息插入其路由表中。

Torrent 文件擴(kuò)展名

一個(gè) Trackerless 種子詞典沒有 “發(fā)行” 鍵值。相反,Trackerless 的種子有一個(gè) “節(jié)點(diǎn)” 鍵值。此鍵值應(yīng)設(shè)置為種子生成客戶端路由表中的 K 個(gè)最近的節(jié)點(diǎn)?;蛘撸梢詫⒚荑€設(shè)置為已知良好的節(jié)點(diǎn),例如由生成種子的人操作的節(jié)點(diǎn)。請不要自動添加 “Router.Bittorrent.Com” 到種子文件或自動將此節(jié)點(diǎn)添加到客戶端路由表中。

nodes = [["<host>", <port>], ["<host>", <port>], ...] nodes = [["127.0.0.1", 6881], ["your.router.node", 4804], ["2001:db8:100:0:d5c8:db3f:995e:c0f7", 1941]]

KRPC 協(xié)議

KRPC 協(xié)議是一個(gè)簡單的 RPC 機(jī)制,由通過 UDP 發(fā)送的編碼字典組成。發(fā)送單個(gè)查詢數(shù)據(jù)包,并發(fā)送單個(gè)數(shù)據(jù)包作為響應(yīng),沒有重試。有三種消息類型:查詢、響應(yīng)和錯(cuò)誤。對于 DHT 協(xié)議,有四個(gè)查詢:ping 、 find_node 、 get_peers 和 announce_peer 。

每個(gè) KRPC 消息是單個(gè)哈希表,每個(gè)消息具有三個(gè)通用鍵,并根據(jù)消息類型提供其他鍵值。每條消息都有一個(gè)鍵 “t”,其字符串值表示事務(wù) ID 。此事務(wù) ID 由查詢節(jié)點(diǎn)生成,并在響應(yīng)中回顯,因此響應(yīng)可能與對同一節(jié)點(diǎn)的多個(gè)查詢相關(guān)聯(lián)。事務(wù) ID 應(yīng)編碼為一小串二進(jìn)制數(shù)字,通常 2 個(gè)字符就足夠了,因?yàn)樗鼈兒w 2^16 個(gè)未完成的查詢。每條消息還有一個(gè)鍵 “y”,其中包含描述消息類型的單個(gè)字符值。 “y” 鍵的值是 “q” 表示查詢,“r” 表示響應(yīng),“e” 表示錯(cuò)誤。在具有客戶端版本字符串的每條消息中都應(yīng)包含一個(gè)鍵 “v” 。并非所有實(shí)現(xiàn)都包含 “v” 鍵,因此客戶端不應(yīng)假定它的存在。

Contact Encoding? 聯(lián)系人編碼

一種緊湊型表示 Peer 節(jié)點(diǎn)聯(lián)系信息的編碼方式,也被稱為 “壓縮 IP 地址/端口信息” 。在這種編碼方式下,一個(gè) Peer 節(jié)點(diǎn)的聯(lián)系信息被表示成 6 個(gè)字節(jié)的字符串。其中前 4 個(gè)字節(jié)表示該 Peer 節(jié)點(diǎn)的 IP 地址,并且采用網(wǎng)絡(luò)字節(jié)序(即大端序)進(jìn)行編碼;后兩個(gè)字節(jié)則表示該 Peer 節(jié)點(diǎn)的端口號,同樣采用網(wǎng)絡(luò)字節(jié)序進(jìn)行編碼。具體地,這 6 個(gè)字節(jié)的排列順序是先表示 IP 地址,再表示端口號,因此拼接成的字符串就是 IP 地址+端口號 的形式。

例如,如果一個(gè) Peer 的 IP 地址是 192.168.1.100,端口號是 6881,那么它的聯(lián)系信息就可以被表示成一個(gè) 6 個(gè)字節(jié)的字符串:

c0 a8 01 64 1a e1

其中,前 4 個(gè)字節(jié)?c0 a8 01 64?表示了 IP 地址 192.168.1.100,后 2 個(gè)字節(jié)?1a e1?則表示了端口號 6881,兩部分按照 IP 地址在前、端口號在后的順序拼接起來,就得到了這個(gè) 6 個(gè)字節(jié)的字符串。

節(jié)點(diǎn)信息采用的是不同的編碼方式。聯(lián)系節(jié)點(diǎn)的信息被編碼為一個(gè) 26 字節(jié)的字符串,其中包含了 20 字節(jié)的節(jié)點(diǎn) ID 和 6 字節(jié)的 IP 地址和端口號信息。這種編碼方式也被稱為” 緊湊型節(jié)點(diǎn)信息” 。節(jié)點(diǎn)可以使用這些信息來連接其他對等方并進(jìn)行文件共享。

Queries? 查詢

當(dāng)發(fā)送一個(gè)請求時(shí),消息字典的”y” 鍵設(shè)置為”q”,表示這是一個(gè)查詢請求。此外,消息字典還需要包含”q” 和”a” 兩個(gè)鍵。其中”q” 鍵指定具體的查詢類型,”a” 鍵則包含了查詢所需的參數(shù)。

Responses? 反應(yīng)

根據(jù) KRPC 協(xié)議規(guī)定,消息字典中包含一個(gè)”y” 鍵,表示消息類型,如果其值為”r”,則表示這是一個(gè)響應(yīng)消息。在這種情況下,消息字典還必須包含一個(gè)額外的”r” 鍵,其值為一個(gè)字典,其中包含了命名的返回值。

當(dāng)節(jié)點(diǎn)收到請求消息并成功處理后,它將發(fā)送一個(gè)響應(yīng)消息來回復(fù)請求方。這個(gè)響應(yīng)消息采用相同的格式,但”y” 鍵的值為”r”,同時(shí)包含一個(gè)額外的”r” 鍵,其值為一個(gè)字典,包含了響應(yīng)的返回值。通過這種方式,節(jié)點(diǎn)之間可以進(jìn)行查詢和回復(fù),實(shí)現(xiàn)基本的通信和交互。

Errors? 錯(cuò)誤

在 KRPC 協(xié)議中,當(dāng)消息字典中的”y” 鍵值為”e” 時(shí),表示這是一個(gè)錯(cuò)誤消息。這種情況下,消息字典會包含一個(gè)額外的”e” 鍵,其值為一個(gè)列表。該列表的第一個(gè)元素是一個(gè)整數(shù),表示錯(cuò)誤代碼,第二個(gè)元素是一個(gè)字符串,包含了錯(cuò)誤信息。這種情況通常會出現(xiàn)在節(jié)點(diǎn)收到請求消息但無法處理時(shí),或者由于某些原因?qū)е抡埱鬅o法完成。通過發(fā)送錯(cuò)誤消息,請求方可以了解到錯(cuò)誤的具體原因,從而采取相應(yīng)的措施。

下表描述了可能的錯(cuò)誤代碼:

錯(cuò)誤數(shù)據(jù)包示例:

generic error = {"t":"aa", "y":"e", "e":[201, "A Generic Error Ocurred"]} bencoded = d1:eli201e23:A Generic Error Ocurrede1:t2:aa1:y1:ee

DHT 查詢

所有的查詢和響應(yīng)消息都包含一個(gè)”ID” 鍵,并且該鍵的值包含了發(fā)出查詢或響應(yīng)的節(jié)點(diǎn)的 ID 。對于查詢消息,請求方會將自己的節(jié)點(diǎn) ID 作為 “ID” 鍵的值附加到消息字典中。當(dāng)接收方節(jié)點(diǎn)收到查詢消息后,它會將自己的節(jié)點(diǎn) ID 作為 “ID” 鍵的值附加到響應(yīng)消息中,以便請求方在接收到響應(yīng)后可以確定響應(yīng)來自哪個(gè)節(jié)點(diǎn)。

通過使用 “ID” 鍵,節(jié)點(diǎn)之間可以建立起基本的通信和交互,使得每個(gè)節(jié)點(diǎn)都可以識別和跟蹤來自其他節(jié)點(diǎn)的查詢和響應(yīng)消息。

Ping?

The most basic query is a ping. “q” = “ping” A ping query has a single argument, “id” the value is a 20-byte string containing the senders node ID in network byte order. The appropriate response to a ping has a single key “id” containing the node ID of the responding node.
最基本的查詢是 ping 。 “q” = “ping” ping 查詢具有單個(gè)參數(shù),“id” 該值是一個(gè) 20 字節(jié)的字符串,包含按網(wǎng)絡(luò)字節(jié)順序排列的發(fā)送方節(jié)點(diǎn) ID 。對 ping 的相應(yīng)響應(yīng)具有包含響應(yīng)節(jié)點(diǎn)的節(jié)點(diǎn) ID 的單個(gè)鍵 “id” 。

在 KRPC 協(xié)議中,“ping” 是最基本的查詢類型之一,用于檢測目標(biāo)節(jié)點(diǎn)是否在線和響應(yīng)正常。 “ping” 查詢包含一個(gè)參數(shù) “ID”,其值為 20 字節(jié)的字符串,在網(wǎng)絡(luò)字節(jié)順序下表示發(fā)送方節(jié)點(diǎn)的 ID 。當(dāng)接收到 “ping” 查詢消息后,節(jié)點(diǎn)會簡單地回復(fù)一個(gè)帶有節(jié)點(diǎn) ID 的響應(yīng)消息作為確認(rèn)。該響應(yīng)消息僅包含一個(gè)鍵 “ID”,其值為響應(yīng)方節(jié)點(diǎn)的 ID 。

通過發(fā)送”ping” 查詢消息和接收響應(yīng)消息,節(jié)點(diǎn)可以確定目標(biāo)節(jié)點(diǎn)是否處于在線狀態(tài),并且與之建立連接的準(zhǔn)備情況。這是建立 P2P 網(wǎng)絡(luò)中最基本的通信方式之一。

arguments: ?{"id" : "<querying nodes id>"} response: {"id" : "<queried nodes id>"}

示例數(shù)據(jù)包

ping Query = {"t":"aa", "y":"q", "q":"ping", "a":{"id":"abcdefghij0123456789"}} bencoded = d1:ad2:id20:abcdefghij0123456789e1:q4:ping1:t2:aa1:y1:qeResponse = {"t":"aa", "y":"r", "r": {"id":"mnopqrstuvwxyz123456"}} bencoded = d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re

Find_node

在 KRPC 協(xié)議中,“find_node” 用于查找給定節(jié)點(diǎn) ID 的聯(lián)系信息。 “find_node” 查詢包含兩個(gè)參數(shù):“ID” 代表請求方節(jié)點(diǎn)的 ID,“target” 代表查詢目標(biāo)節(jié)點(diǎn)的 ID 。

當(dāng)一個(gè)節(jié)點(diǎn)接收到 “find_node” 查詢消息后,它會根據(jù)自己的路由表和查詢目標(biāo)節(jié)點(diǎn)的 ID 來確定響應(yīng)內(nèi)容。如果該節(jié)點(diǎn)具有查詢目標(biāo)節(jié)點(diǎn)的聯(lián)系信息,則會將其作為字符串格式的緊湊節(jié)點(diǎn)信息附加到響應(yīng)消息的 “nodes” 鍵值中返回。如果該節(jié)點(diǎn)沒有查詢目標(biāo)節(jié)點(diǎn)的聯(lián)系信息,則會返回其自身路由表中與查詢目標(biāo)節(jié)點(diǎn) ID 距離最近的 K(通常為 8)個(gè)節(jié)點(diǎn)的緊湊節(jié)點(diǎn)信息。

通過使用 “find_node” 查詢消息和接收響應(yīng),節(jié)點(diǎn)可以了解到其他節(jié)點(diǎn)的聯(lián)系信息,并且進(jìn)行網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)的構(gòu)建和維護(hù)。

arguments: ?{"id" : "<querying nodes id>", "target" : "<id of target node>"} response: {"id" : "<queried nodes id>", "nodes" : "<compact node info>"}

示例數(shù)據(jù)包

find_node Query = {"t":"aa", "y":"q", "q":"find_node", "a": {"id":"abcdefghij0123456789", "target":"mnopqrstuvwxyz123456"}} bencoded = d1:ad2:id20:abcdefghij01234567896:target20:mnopqrstuvwxyz123456e1:q9:find_node1:t2:aa1:y1:qeResponse = {"t":"aa", "y":"r", "r": {"id":"0123456789abcdefghij", "nodes": "def456..."}} bencoded = d1:rd2:id20:0123456789abcdefghij5:nodes9:def456...e1:t2:aa1:y1:re

Get_peers

在 KRPC 協(xié)議中,“get_peers” 用于獲取與特定 Torrent 的 infohash 相關(guān)聯(lián)的節(jié)點(diǎn)列表。 “get_peers” 查詢包含兩個(gè)參數(shù):“ID” 代表請求方節(jié)點(diǎn)的 ID,“info_hash” 代表要查詢的 Torrent 文件的 infohash 。

當(dāng)一個(gè)節(jié)點(diǎn)接收到 “get_peers” 查詢消息后,它會根據(jù)自己存儲的信息確定響應(yīng)內(nèi)容。如果該節(jié)點(diǎn)本身有與所查詢 Torrent 的 infohash 相關(guān)聯(lián)的 peer,則它會將這些 peer 的緊湊格式信息作為字符串附加到響應(yīng)消息的 “values” 鍵中返回。每個(gè)字符串表示一個(gè) peer 的緊湊格式信息。

如果該節(jié)點(diǎn)沒有與所查詢 Torrent 的 infohash 相關(guān)聯(lián)的 peer,則它將返回其自身路由表中與 infohash 距離最近的 K(通常為 8)個(gè)節(jié)點(diǎn)的緊湊節(jié)點(diǎn)信息,其作為字符串格式的聯(lián)系信息附加到響應(yīng)消息的 “nodes” 鍵值中返回。無論是哪種情況,響應(yīng)消息都包含了一個(gè) “token” 鍵,其值是一個(gè)短的二進(jìn)制字符串。這個(gè) TOKEN 鍵可以用作未來 “announce_peer” 查詢的必需參數(shù)。

通過使用”get_peers” 查詢消息和接收響應(yīng),節(jié)點(diǎn)可以了解到與特定 Torrent 的 infohash 相關(guān)聯(lián)的節(jié)點(diǎn)列表,并進(jìn)行相應(yīng)的連接和交互。

arguments: ?{"id" : "<querying nodes id>", "info_hash" : "<20-byte infohash of target torrent>"} response: {"id" : "<queried nodes id>", "token" :"<opaque write token>", "values" : ["<peer 1 info string>", "<peer 2 info string>"]} or: {"id" : "<queried nodes id>", "token" :"<opaque write token>", "nodes" : "<compact node info>"}

示例數(shù)據(jù)包:

get_peers Query = {"t":"aa", "y":"q", "q":"get_peers", "a": {"id":"abcdefghij0123456789", "info_hash":"mnopqrstuvwxyz123456"}} bencoded = d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz123456e1:q9:get_peers1:t2:aa1:y1:qeResponse with peers = {"t":"aa", "y":"r", "r": {"id":"abcdefghij0123456789", "token":"aoeusnth", "values": ["axje.u", "idhtnm"]}} bencoded = d1:rd2:id20:abcdefghij01234567895:token8:aoeusnth6:valuesl6:axje.u6:idhtnmee1:t2:aa1:y1:reResponse with closest nodes = {"t":"aa", "y":"r", "r": {"id":"abcdefghij0123456789", "token":"aoeusnth", "nodes": "def456..."}} bencoded = d1:rd2:id20:abcdefghij01234567895:nodes9:def456...5:token8:aoeusnthe1:t2:aa1:y1:re

Announce_peer?

宣布控制查詢節(jié)點(diǎn)的對等方正在端口上下載種子。 announce_peer 有四個(gè)參數(shù):“id” 包含查詢節(jié)點(diǎn)的節(jié)點(diǎn) ID,“info_hash” 包含種子的信息哈希,“port” 包含端口作為整數(shù),以及響應(yīng)上一個(gè) get_peers 查詢而收到的 “token” 。

一個(gè)節(jié)點(diǎn)可以向其他節(jié)點(diǎn)查詢特定種子文件的 peer 列表,并通過 announce_peer 請求告知其他節(jié)點(diǎn)它正在下載該特定種子文件,并提供其端口號和之前收到的 token 以驗(yàn)證其身份。被查詢的節(jié)點(diǎn)需要驗(yàn)證令牌是否來自相同的 IP 地址,并將查詢節(jié)點(diǎn)的 IP 地址和端口號存儲在其 peer 聯(lián)系信息的相應(yīng) infohash 下。這樣其他節(jié)點(diǎn)就可以向該節(jié)點(diǎn)連接來下載該特定種子文件。

一個(gè)可選參數(shù) implied_port,其取值為 0 或 1 。若該參數(shù)存在且非零,則應(yīng)忽略 port 參數(shù),并使用 UDP 數(shù)據(jù)包的源端口作為對等方的端口。這對于位于 NAT 后面的對等方很有用,因?yàn)樗麄兛赡懿恢雷约旱耐獠慷丝?,同時(shí)支持 uTP 協(xié)議,它們在與 DHT 端口相同的端口上接受傳入連接。

arguments: ?{"id" : "<querying nodes id>", ?"implied_port": <0 or 1>, ?"info_hash" : "<20-byte infohash of target torrent>", ?"port" : <port number>, ?"token" : "<opaque token>"} response: {"id" : "<queried nodes id>"}

示例數(shù)據(jù)包:

announce_peers Query = {"t":"aa", "y":"q", "q":"announce_peer", "a": {"id":"abcdefghij0123456789", "implied_port": 1, "info_hash":"mnopqrstuvwxyz123456", "port": 6881, "token": "aoeusnth"}} bencoded = d1:ad2:id20:abcdefghij012345678912:implied_porti1e9:info_hash20:mnopqrstuvwxyz1234564:porti6881e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qeResponse = {"t":"aa", "y":"r", "r": {"id":"mnopqrstuvwxyz123456"}} bencoded = d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re

參考鏈接

  • http://bittorrent.org/beps/bep_0005.html

  • https://hazelcast.com/glossary/distributed-hash-table/

  • https://en.wikipedia.org/wiki/Distributed_hash_table


DHT 協(xié)議具體是什么呢?的評論 (共 條)

分享到微博請遵守國家法律
收藏| 兴文县| 贺兰县| 长垣县| 嘉黎县| 定日县| 易门县| 高邑县| 长宁县| 韶关市| 舞钢市| 崇明县| 文山县| 丰都县| 平度市| 安化县| 杭州市| 安丘市| 贺州市| 嘉善县| 日照市| 博客| 科尔| 荆门市| 阜城县| 黎城县| 太康县| 都安| 彭山县| 宜都市| 翁牛特旗| 南陵县| 泰和县| 铅山县| 苏州市| 正镶白旗| 新竹县| 哈尔滨市| 乌审旗| 米脂县| 阿拉善左旗|