众所周知,当我们想要下载一个盗版电影或者是某些不可描述的东西的时候,首先会去寻找这个资源的磁力链接,然后通过迅雷或者百度网盘等方式下载资源。那么,磁力链接到底是什么呢?又是如何通过一个磁力链接来获取资源的呢?
在了解磁力链接之前,我们先了解一下BitTorrent。
BitTorrent
以下是维基百科对于BitTorrent的解释
BitTorrent协议(简称BT,俗称比特洪流、BT下载)是用在对等网络中文件分享的网络协议程序。和点对点(point-to-point)的协议程序不同,它是用户群对用户群(peer-to-peer),而且用户越多,下载同一文件的人越多,下载该文件的速度越快。且下载后,继续维持上传的状态,就可以“分享”,成为其用户端节点下载的种子文件(.torrent),同时上传及下载。
BitTorrent是一个协议,就像是计算机网络中的HTTP协议那样。他通过DHT来保存拥有资源的客户端的信息。
以下是百度百科对于DHT的解释。
DHT全称叫分布式哈希表(Distributed Hash Table),是一种分布式存储方法。在不需要服务器的情况下,每个客户端负责一个小范围的路由,并负责存储一小部分数据,从而实现整个DHT网络的寻址和存储。
从中我们可以了解到DHT是分布式的,也就是说资源并不存储在某一个特定的服务器上,而是分布在整个DHT网络之中。
在DHT网络之中,客户端被称为Node,拥有资源的客户端被称为Peer。所有的客户端和资源都有一个160位(20字节)的id,主机叫NodeId,资源叫InfoHash。举个栗子:4D9FA761D69964B00DF0B3B0C9C1F968EA6C47D0。可以看到,id由40个16进制位组成,也就是20字节。
- magnet:协议名。
- xt:exact topic的缩写,包含文件哈希值的统一资源名称。BTIH(BitTorrent Info Hash)表示哈希方法名,这里还可以使用ED2K,AICH,SHA1和MD5等。这个值是文件的标识符,是不可缺少的。
- urn:(Uniform Resource Name, URN 表示资源名
- btih:BitTorrent info hash,种子散列函数
由此,第一个问题得到了解答,我们来看第二个问题,也是本章的重点:迅雷是如何通过磁力链接获取资源的?
要回答这个问题,我们得深入了解一下BitTorrent协议
通过磁力链接获取资源
在BitTorrent协议中有4种操作:
ping
用来检查Node状态,用以更新Routing table。
find_node
通常是用来初始化Routing table,因为一开始,Routing table是空的,我们需要通过向公共节点发送find_node来填充之。
get_peers
当用户要下载种子资源时向其它Node发起。如果Node有该资源,则返回资源的下载端口以供对方下载,如果没有,则根据异或算法在自己的Routing table中寻找离资源最近的Node返回给对方,对方如此递归发送get_peers,直到找到资源为止。
announce_peer
当一个用户下载完种子资源,种子开始下载时通知所有曾经get_peers咨询过的node。
上面提到了一个概念:Routing table,路由表。在DHT网络中, 每个节点都会维护一张路由表,用来存储离别的节点的信息。节点与节点之间的距离并不是物理上的距离,而是逻辑上的距离,这个距离通过异或算法来得到。
所以,迅雷其实是实现了这个BitTorrent协议,通过get_peers来获取存储资源的节点,然后向他们请求资源。下载资源的用户可能会把资源存储在本机中,让自己也成为一个peer,这也就是为什么下载一个资源的用户越多,下载速度就越快。
恰饭时间
我用Node实现了一个基于BitTorrent协议的BT种子搜索器,有兴趣的童鞋可以看看,如果觉得还不错的话,麻烦点一个star,谢谢了~