Advertisement

bt协议详解 DHT篇(上)

阅读量:

bt协议详解 DHT篇(上)

最近开始开发了一个免费在线教程平台](https://www.tutorialonfree.com/), 突然激发了深入学习bt协议的兴趣, 文章将作为《bt协议详解系列》中的第三期发布, 后续计划分享搜索优化及索引构建的相关内容, 这些都源于我在创建这个平台过程中积累的技术经验, 期待您的关注与指导

文章主要内容基于对DHT Protocol的转录或转换, 如若感兴趣, 可参考英文原文.

为了让读者阅读更加轻松,并非简单的分割文字而是将内容进行了系统性的梳理与整合;经过统计计算总长度已经超过了一万字左右;真的觉得阅读起来非常辛苦

1 简介

在介绍网络层时提到过,在那个体系架构中将BT(BitTorrent)与TCP/IP并置作为核心组件之一。而在该领域的发展过程中将DHT(分布式哈希表)这一技术提出得稍微晚一些时间,并且其贡献却不可小觑。然而它的创新性在于提出了许多颠覆性思维不仅颠覆性地改变了基础篇中的设计理念也使得我们能够构建出一个更为简洁高效、易于使用的BT服务器与客户端系统。

按照dht协议,“bt客户端采用分布式松散哈希表(DHT缩略语形式)来存储那些没有tracker地址的种子文件对应的所有peer节点信息,在这种情况下,在这样的情况下,“每一个peer节点充当了一个tracker节点,在这种架构下,“dht协议基于UDP通信协议并采用Kad算法进行开发。”

重要:请特别注意以下术语:peert型节点遵循了BT协议,并且启用了TCP监听端口作为BT客户端或服务器;peert型节点遵循了分布式哈希表协议,并且启用了UDP监听端口作为BT客户端或服务器;这两个术语很容易混淆。

dht由大量node构成,并且每个node都存储了与之相关的 peer地址信息。每个bt客户端包含一个位于该分布式哈希表上的 node 节点,并通过与该网络中的其他 node 进行通信来获取相关的 peer 信息。随后利用 bt 协议从相应的 peer 处下载文件。

在这里大家应该明白了

2 概述

在DHT网络架构中,每个参与者即为一个'node'(即'nodes'),其内部都会拥有唯一的标识码——称为node ID(缩写为nID)。这个nID会被从参与者提供的种子文件中的160位哈希值集合中随机抽取出来作为身份标识。为了衡量不同nID之间的相似性或差异程度,在系统运行过程中我们采用distance metric这一指标来进行量化评估。在构建网络连接时,每个参与者都需要维护一个路由表来记录与少量关键参与者之间的联系信息。具体而言,在当前系统架构下:与所在位置较近的位置拥有更详细的相关参与者信息;而那些处于远端位置的参与者则仅需保证基本连接次数即可满足需求

在Kad算法框架内进行的距离计算过程是通过对两个hash值执行异或运算,并将其转换为无符号整数形式来实现的。distance(A,B)等于|A xor B|的结果数值越大表示两者之间的接近程度越高。

为了获取正在下载该种子文件的所有peers信息,网络实体将执行以下操作:首先运用距离算法计算目标种子文件哈希值与本地路由表中各记录之间的差异程度。随后将此计算结果反馈至当前最近连接的目标实体,并询问其是否掌握该资源的所有peers列表。若目标方能够提供该资源的所有peers列表,则完整地返回这些peers信息;反之,若无法获取相关信息,则采用本地路由表中与目标哈希值最接近的数据结构作为补充。该过程不断迭代调整直至定位到具有最小哈希差异的目标数据结构。

该命令返回的结果可能包含一个可选参数' token '。
如果某个节点声称其管理的一组 peer 节点中有某台机器正在上传种子文件,则该节点应将最新的请求中的 ' token ' 传递给负责处理这些请求的任务。
每当某个任务试图注册新的种子文件时,
回应方会验证这个 ' token ' 以及提供相关 IP 地址。
这一机制旨在防止假 pretend 操作。
值得注意的是,
该协议允许 tokens 在部署后持续发挥作用一段时间,
而 bittorrent 客户端则会根据设定每隔 5 分钟更换一次密钥,
从而确保生成的有效 tokens 可维持 10 分钟之久。

3 路由表

每一个网络设备都管理一个路由表用于存储一些可靠通信的设备地址。作为起点使用,在该设备接收到其他网络设备的请求时(即发送请求方),将被转发给这些存储在路由表中的设备地址。

并非所有已知 node 都是平等 的 。其中一些 node 是活跃 的 (如前所述 ),另一些则不然 。DHT 网络中存在许多能够发送 request 并响应返回 的 node ,但这些 node 也不会主动响应 来自其他 DHT node 的 request 。每个 node 的路由表仅存储经过验证 的 有效 node 信息 ,这一点非常重要 。活跃 node 是指在过去 15 分钟内至少成功响应一次 request 或发送一次 request 的 node 。如果一个 node 在过去 15 分钟内没有任何活动 ,则被标记为有问题 。当某个 DHT node 无法成功 response request 时 ,则被视为故障 node 。活跃node 在优先级上明显高于处于未知状态 的 所有node (这是不言而喻的事实)。

路由表覆盖从0到2160完整的nodeID空间。路由表又被划分为buckets(桶),每一个bucket包含一个子部分的nodeID空间。一个空的路由表只有一个bucket,它的ID范围从min=0到max=2160。当一个nodeID为“N”的node插入到表中时,它将被放到ID范围在min< N < max的bucket中。一个空的路由表只有一个bucket所以所有的node都将被放到这个bucket中。每一个bucket最多只能保存K个nodes,当前K=8。当一个bucket放满了好的nodes之后,将不再允许新的节点加入,除非我们自身的nodeID在这个bucket的范围内。在这样的情况下,这个bucket将被分裂为2个新的buckets,每一个新桶的范围都是原来旧桶的一半。原来旧桶中的nodes将被重新分配到这两个新的buckets中。如果是一个只有一个bucket的新表,这个包含整个范围的bucket将总被分裂为2个新的buckets,第一个的覆盖范围从0..2159,第二个的范围从2159..2160。

当桶满了健康的组件,则会舍弃多余的组件。一旦桶中发现了一个故障组件,则会采用新的组件来替代它。如果存在长时间未活跃组件,则将其标记为可疑组件,并向最后一个未响应的目标发送超时探测包。直到某个目标未能响应超时探测包或者当前系统中所有剩余组件都是健康的(即所有组件都不是可疑组件,在过去15分钟内都有活动)。如果发现某个组件未能响应超时探测包,则最好再次尝试(重新发送超时探测包)而不是立即丢弃该组件或者将其替换为新组件。因此,在路由表中将积累稳定的长时间在线组件。

每个桶都应保留一个“lastchanged”字段以指示桶内节点的新鲜程度。每当桶内的节点被ping回响应、被加入或被新节点替代时,该桶的“lastchanged”字段需更新。若该桶在过去的15分钟内未更新过“lastchanged”值,则需进行一次更新操作。此更新操作可通过以下步骤完成:从当前覆盖区域中随机选取一个ID,并对该ID执行find_nodes查找操作以获取相关节点信息。通常而言,在高负载情况下运行频繁请求的节点应定期进行find_node消息广播以维护其相关的buckets;而低负载区域则可相对较少地执行此操作以节省资源,在必要时仍能确保DHT系统中拥有足够优质的节点可供使用。
当第一个node启动路由表服务后,在其运行过程中应尝试寻找与其更接近的邻居节点以便优化路由表结构。这一查找过程是通过不断发布find_node消息给逐渐靠近的目标节点来实现的;当无法找到比当前已知距离更近的目标时则停止这一扩散过程。

4 bt协议扩展

现已被扩展为一种可以让通过tracker获得的peers之间彼此交换nodeUDP端口号的方式,并指示它们提供我们的DHT服务端口号,在这种情况下,“客户端能够通过获取普通种子文件来自动构建其DHT路由表。首次尝试从不带tracker支持的新安装客户端中获取种子文件时,“该客户端发现其本地路由表空无所有。”这使得它必须在torrent文件中查找与这些节点相关联的信息才能继续运行。

peers如果支持采用DHT协议,则需在BitTorrent协议握手消息保留位第8位进行设置。
当这些节点接收到一个handshake消息表明对方支持使用DHT协议时,
应发送该类型的消息。
该数据字段从字节0x09开始,
其长度占用了两个字节,
包含了该连接所使用的UDP端口号信息。
当接收方接收到此类数据时,
则应向目标节点发送响应请求。
若目标节点返回了响应确认,
则可按照前述方法更新路由表中的相关节点信息。

本文来自 免费教程网

转载于:https://my.oschina.net/ideras/blog/689669

全部评论 (0)

还没有任何评论哟~