本地服務發現機制 Local Service Discovery (LSD) 提供類似於 SSDP 的機制(通過 UDP 多播的 HTTP 協議),向本地鄰居宣告其在特定群組中的存在。這樣能夠讓其他本地設備知道該設備提供了哪些服務,從而方便彼此之間的通信和數據傳輸。這個機制可以作為本地傳輸的主要對等方來源,也可以用來補充其他僅在全局單播地址上運行的來源。
協議#
LSD 使用以下多播組:A) 239.192.152.143:6771 (org-local)
和 B) [ff15::efc0:988f]:6771 (site-local)
。
實施註釋:由於多播組比本地局域網更廣泛,因此可能需要將 IP_MULTICAST_TTL 套接字選項設置為一個大於默認值的值。
LSD 協議的 announce 消息格式:
BT-SEARCH * HTTP/1.1\r\n
Host: <host>\r\n
Port: <port>\r\n
Infohash: <hash>\r\n
cookie: <cookie (optional)>\r\n
\r\n
\r\n
host#
Host 需要同時滿足 RFC 2616 section 14.23 和 RFC 2732 的規範要求,用於指定 announce 消息發送到的組播組地址。
RFC 2616 是 HTTP/1.1 的規範文件,它定義了一系列關於 HTTP 協議的信息。其中,section 14.23 描述了 Host 頭部的格式。 Host 頭部用於指定請求的目標服務器的主機名和端口號。而 RFC 2732 則是一個 URL 的標準,它允許使用 IPv6 地址來表示 URL 中的主機名。這意味著在 LSD 協議的 Host 頭部中,可以使用 IPv6 地址來表示組播組的地址。
port#
這個字段指定了 bittorrent 客戶端正在監聽的端口號,以 base-10 ASCII 編碼表示。
hash#
這個字段是一個 40 位的十六進制編碼的 infohash 值,用於唯一標識一個種子文件。
當發送多個 infohashes 時,需要注意儘量避免數據包長度超過 1400 字節,以避免 MTU / 分片 問題。因為在網絡傳輸過程中,如果數據包長度超過 MTU(最大傳輸單元)的大小,就會發生 IP 分片,導致網絡傳輸效率降低和數據包丟失的風險增加。
cookie#
不透明的值,這個值對客戶端來說是完全未知和不可見的,因此它只需要被發送給客戶端,而不需要進一步解釋。該值的作用是允許發送客戶端在接收到自己發送的 announce 請求時進行過濾,以避免重複處理。
任何客戶端不理解的額外頭部信息都應該被忽略,以確保前向兼容性。
實現#
首先,如果一個客戶端正在參與一個 swarm,那麼它應該每隔 5 分鐘在每個接口上發送一個 LSD announce,以便其他客戶端可以知道它的存在並連接到它。為了避免在大型網絡中引起組播風暴,客戶端每分鐘最多只能發送一次通告。
其次,如果一個客戶端正在同時進行 5 個以上的 torrent 下載或上傳,那麼它可以選擇輪流在其中的每個 torrent 上發送通告,也可以在單個通告中包含多個 infohashes(區分不同 torrent 的哈希值)。這樣其他客戶端可以使用這些信息來建立與客戶端的連接。
當一個客戶端接收到另一個客戶端的 LSD 通告時,它需要根據 UDP 源地址來確定如何聯繫遠程客戶端的 IP 地址。
總結#
在 BitTorrent 協議中,Local Service Discovery (LSD) 是一種本地服務發現機制,用於發現局域網內的其他 BitTorrent 客戶端。當一個 BitTorrent 客戶端啟動時,它會通過 LSD 廣播自己的存在,並接收來自其他客戶端的廣播信息,從而建立起點對點的連接。
LSD 通過使用 UDP 多播方式,在局域網內快速地發現其他客戶端。同時,LSD 還可以與其他本地服務發現協議(如 mDNS)結合使用,進一步提高對局域網內設備的發現效率。
LSD 是 BitTorrent 協議中的一個重要組成部分,它可以加速 P2P 下載過程中的節點發現,提高文件下載的速度和穩定性。