Magnet,神秘而又充满魅力的名词,听起来很陌生,却在我们日常网络下载中扮演着重要的角色。它是如何诞生的?历经了怎样的岁月沉淀?Magnet 其实是一种特殊的下载链接,可以让我们更加方便快捷地下载网络资源。早期,输入文件名或者 URL 地址,是我们下载资源的唯一方式。这样容易出现错误或者下载失败的情况。这种方法不仅效率低下,也很容易让人感到沮丧。
而 Magnet 是通过计算机生成的磁力链接,带来了革命性的变化。磁力链接精准自动,让下载变得轻松又愉快。随着 P2P 技术的不断发展,Magnet 也在不断演进,逐渐成为了 BT(BitTorrent)下载方式的标配。与传统的 HTTP 下载方式相比,BT 下载可以实现多节点同时下载、断点续传等功能,大幅提升了下载速度和成功率。今天,Magnet 已经成为了网络下载的主流方式之一,在我们获取网络资源时发挥着越来越重要的作用。
Magnet 最初的名字叫做 Extension for Peers to Send Metadata Files。对,你没看错,最初它是作为节点传输元数据的扩展程序诞生的。
这款扩展的目的是允许客户端加入一个节点网络并完成下载,而无需先下载种子(.torrent)文件。取而代之的是,这个扩展程序允许客户端从其他节点处下载元数据。这样就可以支持磁力链接,即网页上仅包含足够信息以加入节点网络(信息哈希)的链接。
Metadata 元数据
这个扩展程序只传输种子(.torrent)文件的信息字典部分。该部分可以通过信息哈希进行验证。在该文档中,种子(.torrent)文件的这一部分被称为元数据。元数据以 16KiB(16384字节)的块处理。元数据块从 0 开始索引。所有块大小固定都是 16KiB,除了最后一个块可能会小于 16KiB。
extension header 扩展头部
元数据扩展通过规定的扩展协议来进行通信。在与其他节点进行握手时,它会在握手消息的 “m” 字典中添加一个名为 “ut_metadata” 的条目来表明它的存在,并且还会在握手消息中添加一个名为 “metadata_size” 的字段来指定元数据的大小。这些信息可以帮助其他节点了解如何与元数据扩展进行通信和交换元数据。
示例分机握手消息
{'m': {'ut_metadata', 3}, 'metadata_size': 31235}
extension message 扩展消息
扩展消息已编码。有 3 种不同类型的消息:
0.request 1.data 2.reject
为了支持未来的可扩展性,在 bencoded
request 请求
request 消息在字典中没有任何额外的键。如果支持此扩展的对等方向此消息的响应为“reject”或“data”消息。响应必须具有与请求相同的数据块索引(piece)。对等方必须验证其发送的任何块通过信息哈希值验证。也就是说,直到对等方拥有完整的元数据,它才能运行 SHA-1 算法来验证是否与信息哈希值产生相同的哈希值。对于没有完整元数据的节点,其必须向任何元数据请求响应一个“reject”消息。
例
{'msg_type': 0, 'piece': 0} d8:msg_typei0e5:piecei0ee
data 数据
数据消息会向字典中添加一个新的条目,名为”total_size”。该键与扩展头部中的”metadata_size”具有相同的语义,都是整数。元数据块被附加到 bencoded 字典中,但它不是字典的一部分,而是消息的一部分(长度前缀必须包括它)。如果元数据块是最后一块,则它的大小可能小于16KiB。如果它不是元数据的最后一块,则必须为16KiB。
例
{'msg_type': 1, 'piece': 0, 'total_size': 3425} d8:msg_typei1e5:piecei0e10:total_sizei34256eexxxxxxxx...
reject 拒绝
reject 消息不包含任何额外的字段。它的含义是,节点中没有被请求的元数据块。客户端可以通过在服务一定数量的请求消息后拒绝请求来防止过度请求(flood protection)。通常,这个数量会根据需要的元数据块数量乘以一个比例因子进行计算。
例:
{'msg_type': 2, 'piece': 0} d8:msg_typei1e5:piecei0ee
Magnet URI 格式
Magnet URI 格式为:
v1: magnet:?xt=urn:btih:<info-hash>&dn=<name>&tr=<tracker-url>&x.pe=<peer-address> v2: magnet:?xt=urn:btmh:<tagged-info-hash>&dn=<name>&tr=<tracker-url>&x.pe=<peer-address>
<info-hash>
是共享的特定种子文件的唯一标识符。info-hash 可以用两种不同的格式表示:
1. 十六进制编码格式——此格式由 40 个字符组成,并使用十六进制编号系统(0-9 和 A-F)来表示每个字符。例如,有效的十六进制编码信息哈希可能如下所示:“3a4c571176ea6d5fdba2a5a4c55f5b56c5e7ac32”。
2. Base32 编码格式——此格式由 32 个字符组成,并使用 base32 编码方案来表示每个字符。此格式用于与公开的现有链接兼容。例如,有效的 base32 编码的信息哈希可能如下所示:“K54TBHPSZZ6JQP53QRU664E5XWDRDR6N”。
<tagged-info-hash>
在新的元数据格式中,infohash 使用了 multihash 多哈希格式编码,并以十六进制编码形式呈现。
其中包含 “btmh” 和 “btih” 这两个概念。其中,“btmh”指的是混合种子(Hybrid Torrent),即同时包含 DHT 节点和 Tracker 服务器地址信息的种子文件,在 magnet 链接中可以使用 “xt=urn:btmh:” 参数来标识;而“btih”则是指使用单一的 tracker 地址进行跟踪的普通 BT 种子,在 magnet 链接中可以使用 “xt=urn:btih:” 参数来标识。可以把它们看成是 BitTorrent 中两种不同类型的种子文件。
如果一个 magnet 链接描述了一个混合种子,那么它可能同时包含 “btmh” 和 “btih” 这两种参数,但它们所表示的实际上是同一个种子文件,只是使用了不同的标识方式而已。
<peer-address>
用于标识其他客户端的地址。这个地址可以使用主机名加端口号、IPv4 地址加端口号或者 IPv6 地址加端口号的形式来表示。当两个客户端需要直接交换元数据时,可以通过使用对等地址来进行直接传输,从而减少对外部节点源的需求。但是,在包含节点地址的时候,必须确保客户端能够发现自己的公共 IP 地址并确定其可访问性。
xt 是唯一的必填参数。 dn 是客户端在等待元数据时可用于显示的显示名称。 tr 是一个跟踪链接(如果有的话)。如果有多个跟踪器,则可能包含多个 tr 条目。这同样适用于 x.pe 个条目
参考链接
- http://www.bittorrent.org/beps/bep_0009.html