@(基础技术)node
如今有一种方法,能够经过磁力连接,例如magnet:?xt=urn:btih:0482e0811014fd4cb5d207d08a7be616a4672daa
,就能够获取BT文件。
这个是经过DHT网络来实现的。
DHT网络是一个去中心化的,分布式信息存储系统。
存储的信息就是bt文件。算法
每一台电脑,就是一个节点。它既是客户端,也是服务端。
每一个节点都有一个节点ID,IP地址和端口号(节点进程的端口)。
节点ID由160位的二进制字符串组成,也就是长度为32的16进制字符串,跟咱们经常使用的md5同样。
经过异或算法,能够计算两个节点ID的距离。例如01和00的异或结果是01,也就是距离是1。json
每一个节点都会保存一个路由表,保存其余节点的信息,节点信息包括:节点ID,节点的IP地址和端口号。
路由表中,会有多个bucket,例如bucket-1,bucket-2等等。
bucket-i保存的是与自身节点ID距离为[2^i-1,2^i)的节点信息
每一个nodeid能够理解为深度是160的二叉树,二bucket-i就是自身的叶子的第i个父节点的兄弟节点的全部叶子节点(不太严谨)
以下图:
服务器
因此i最大值是160。网络
而为何要这么存了?
这样存是为了能够快速找到目标节点N2。
例如自身的节点ID是N1,须要寻找N2的IP和端口号。分布式
由于N2和N3会处于同一个bucket,因此他们的距离D1不会超过D/2,因此每一次循环,得到的节点NN与N2的距离都会比以前的请求缩小1倍。因此时间复杂度是logN。跟二分查找是同样的。加密
当发布者,须要发布信息(例如一个bt文件)到DHT网络。.net
k通常要大于1。否则只会把信息存储在一个节点上,万一节点下线,或者退出网络,就会致使信息不能被找到。线程
节点与节点之间,经过UDP协议,传输数据包来通信。
DHT网络的数据包都是json格式。
必须字段:code
e,错误包,其实也是回复的一种
回复包必须字段:
*r 回复的内容,字典
请求包
a包含字段
包例子
{"t":"aa", "y":"q","q":"ping", "a":{"id":"abcdefghij0123456789"}}
回复包
r包含字段
包例子
{"t":"aa", "y":"r", "r":{"id":"mnopqrstuvwxyz123456"}}
请求包
a包含字段
包例子:
{"t":"aa", "y":"q","q":"find_node", "a":{"id":"abcdefghij0123456789","target":"mnopqrstuvwxyz123456"}}
回复包
r包含字段
包例子
{"t":"aa", "y":"r", "r":{"id":"0123456789abcdefghij", "nodes":"def456..."}}
请求包
a包含字段
包例子
{"t":"aa", "y":"q","q":"get_peers", "a":{"id":"abcdefghij0123456789","info_hash":"mnopqrstuvwxyz123456"}}
回复包
若是回复者的路由表中,有存有info_hash资源的节点信息,就返回value,不然返回node,node的值和find_node同样
r包含字段
包例子
{"t":"aa", "y":"r", "r":{"id":"abcdefghij0123456789", "token":"aoeusnth","values": ["axje.u", "idhtnm"]}}
请求包
a包含字段
包例子
{"t":"aa", "y":"q","q":"announce_peer", "a":{"id":"abcdefghij0123456789","info_hash":"mnopqrstuvwxyz123456", "port":6881, "token": "aoeusnth"}}
回复包
r包含字段
包例子
{"t":"aa", "y":"r", "r":{"id":"mnopqrstuvwxyz123456"}}
e 列表类型,第一个元素时错误id,第二个是错误的说明
{"t":"aa", "y":"e", "e":[201,"A Generic Error Ocurred"]}
错误类型有:
向三个固定服务器发送find_node的请求,target是随机的nodeid或者是本身的nodeid,N1
服务器返回最接近N1的的3个nodeid的信息,这些信息是一个加密了的,固定协议的字符串,里面有node的ip,port和nodeid。自身节点把全部的node存储到路由表
新开一个线程,对node,再发送find_node请求,这时本身的nodeid是随机的
这样,就会致使在不少个DHTNode中,都有咱们ip和端口的信息,并且映射到不少不一样的nodeid
这样别人去这些DHTNode中寻找bt资源的时候,这些Node就极可能会返回咱们的IP,PORT给别人,那么别人就会向咱们发送announce_peer的请求,这样咱们就能拿到bt文件了
当获得BT文件后,就能够用bt文件下载器进行文件的下载
BT文件里面包含
下载流程
因此bt文件的下载过程,并非去中心化的,tracket服务器就是一个中心化的服务器。
tracket服务器只管理下载节点的信息,并不会存储文件的具体分块。因此压力也比较小。
节点越多,下载的速度越快。
未经容许,请不要转载