Ctorrent: 寻找peer 算法分析

本文深入分析了Ctorrent中寻找peer的算法,包括初始模式、一般模式(严格优先与最少优先)和结束模式的实现细节。通过位图管理和请求队列策略,Ctorrent确保高效下载和公平的资源分配。文章还探讨了如何在不同模式下选择最优piece,以及在结束模式下如何加速下载完成。
摘要由CSDN通过智能技术生成

                 Ctorrent:  寻找 peer 算法分析

前言

 

网上有一篇很经典的 ctorrent 分析文章,虽然是用的 1.3 的源码分析的,但是相对我现在看的 3.3.2 的源码, 也只有很少一部分有差异,在寻找 peer 部分比较明显。

这篇文档的作用是补充完整 BT 协议描述的实现寻找 peer 的算法。

 

首先描述算法再结合源码具体分析

 

BT 下载之所以性能出众是由 BT 协议所规定的一系列机制所保证的。判断一个 BT 下载软件性能优秀与否则是看这个软件对 BT 协议中下载机制的执行情况。 BT 协议主要规定了两大类机制保证其性能(详细信息请参照 ” Incentives Build Robustness in BitTorrent” ):

 

3.4.1 P iece 选择机制

3.4.1 .1 初始模式( Initial Mode ): Random First Piece

当客户端刚开始运行时,它一个完整的 piece 也没有,这时需要尽快下载到一个 piece 以便可以提供上传服务。此时的算法为:第一个随机 piece 。客户端会随机找到一个 piece ,然后下载。

 

CTorrent 随机选择 piece ,而且更进一步采取了一种加速下载的办法:虽然此时客户端没有 piece ,但应该有向其它 peer 的申请 slice 的队列了。客户端只要比较这些队列哪个最短,优先下载最短的队列即可最快获得第一个 piece 。(这个是用的位图来实现的)

 

函数 PeerList::Who_Can_Duplicate() 实现了此算法的代码。

 

3.4.1 .2 一般模式( Normal Mode ): Strict Priority Rarest First

1 ,严格优先( Strict Priority

一旦某个 slice 被申请,则这个 slice 所在的 piece 中的其它 slice 会先于其它 piece slice 被申请。这样做可以尽量使最先申请的 piece 最先被下载完毕。

 

这条规则看似简单而且公平,但实现起来非常困难: BT 协议规定一个 piece 中的多个 slice 可以向多个 peer 申请,而客户端又同时从多个 peer 处申请了多个 piece 中的 slice ,这么多数据传输队列同时进行,要保证严格优先是非常困难的。

 

CTorrent 在设计时采取了一种比较简单的方法: 一旦向某个 peer 申请了某个 slice ,则这个 piece 中的所有 slice 均向这个 peer 申请。为了保证尽快将一个 piece 下载完成, CTorrent 会找出当前正在与之通信的那个 peer (正在通信的 peer 通常比较活跃),然后把所有 slice 请求队列中最慢的那个队列找出来,交给这个 peer 去下载。

 

函数 PeerList::Who_Can_Abandon() 实现了此算法的代码。

 

2 ,最少优先( Rarest First

客户端下载时选择所有 peer 拥有最少的那个 piece 优先下载。

函数 BitField::Random() 是有关 piece 选择机制的代码,但它只是随机选择了 piece ,没有实现最少优先。

 

3.4.1 .3 结束模式 (Endgame Mode)

由于每一个 piece 只向一个 peer 申请 ,当 peer 数大于还没有申请的 piece 数时,客户端便进入了结束模式。此时客户端可以向所有的 peer 发送还没有下载完毕的 slice 的请求,以便尽快下载完毕好做种子。

 

CTorrent 变相实现了这个算法,它会找出当前正在与之通信的那个 peer (正在通信的 peer 通常比较活跃),然后把所有 slice 请求队列中最长的那个队列找出来,交给这个 peer 去下载。

 

函数 PeerList::Who_Can_Duplicate() 实现了此算法的代码。

 

函数 PeerList::Who_Can_Duplicate() PeerList::Who_Can_Abandon() 的调用环境均是函数 btPeer::RequestPiece() ,应将这三个函数一起查看才能清楚 piece 选择机制的实现。

 

// 函数主要检查需要向 peer 请求哪一个 piece , 分几种情况

/* 首先检查 request_q 的空间是否足够,一种情况是查看 PENDINGQUEUE 中是否有可以向 peer 请求的数 ?

2: 在不为初始化阶段是接受到 have 消息 3:

 

*/

int btPeer::RequestPiece()

{

  size_t idx;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值