分类: C/C++
2008-03-06 21:00:53
一 、初始模式(Initial Mode):Random First Piece
当客户端刚开始运行时,它一个完整的piece也没有,这时需要尽快下载到一个piece以便可以提供上传服务。此时的算法为:第一个随机piece。客户端会随机找到一个piece,然后下载。
CTorrent随机选择piece,而且更进一步采取了一种加速下载的办法:虽然此时客户端没有piece,但应该有向其它peer的申请slice的队列了。客户端只要比较这些队列哪个最短,优先下载最短的队列即可最快获得第一个piece。
函数PeerList::Who_Can_Duplicate()实现了此算法的代码。
二、 一般模式(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,没有实现最少优先。
三、结束模式(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选择机制的实现。