Linux BT下载(14)-策略管理模块的设计和实现

本文详细介绍了Linux环境下BT下载的策略管理模块,包括policy.c和policy.h的职责,如计算peer下载速度、选择非阻塞peer的优化算法以及片断选择策略。通过每10秒更新速度、保持一个优化非阻塞peer以及30秒重新选择策略,确保高效的数据交换。
摘要由CSDN通过智能技术生成

策略管理模块的设计和实现

策略管理模块由policy.c和policy.h组成,主要负责策略的实现,计算各个peer的下载速度,根据下载速度选择分阻塞的peer,采用随机算法选择优化非阻塞peer,以及实现片断选择策略。

据说BT协议的设计者说计算从各个peer处下载的速度是一个棘手的问题。经过分析和对比,现在通用的计算下载速度的方法是每10秒计算一次速度,并将下载速度最快的4个peer解除阻塞,允许它们从本客户端下载,除一个特殊的peer外其他peer将被阻塞,为了发现更快下载速度的peer,任何时刻保证存在一个优化非阻塞peer,将这个peer解除阻塞,而暂时不管从该peer处下载数据的速度,每隔30秒重新进行选择。在这30秒内,本客户端提供该peer较快的下载速度,然后该peer将本客户端解除阻塞,这样就可以从该peer处下载数据,并在下次选择非阻塞peer时,该peer能成为4个非阻塞的peer中的一个。片断选择策略,也就是选择下载那些slice。


以下是policy.h的代码:

//policy.h
#ifndef POLICY_H
#define POLICY_H
#include "peer.h"

// 本文件实现了bittorrent协议的一些关键算法,主要有:
// 流水作业(一次生成对某个peer的多个slice请求,一般为5个)
// 片断选择算法(针对不同的下载阶段,有不同的选择策略)
// 阻塞算法(根据速度选择非阻塞peer)以及选择优化非阻塞peer
// 判断是否下载完毕(根据位图作出判断,下载完毕即终止程序)

// 每隔10秒计算一次各个peer的上传下载速度
#define COMPUTE_RATE_TIME  10
// 非阻塞peer的个数
#define UNCHOKE_COUNT  4
// 每次请求的slice数
#define REQ_SLICE_NUM  5
// 以下结构体存储下载速度最快的4个peer的指针
typedef struct _Unchoke_peers {
	Peer*  unchkpeer[UNCHOKE_COUNT];// 保存非阻塞peer的指针
	int    count;// 记录当前有多少个非阻塞peer
	Peer*  optunchkpeer;// 保存优化非阻塞peer的指针
} Unchoke_peers;


void init_unchoke_peers();     // 初始化全局变量unchoke_peers


int select_unchoke_peer();     // 选择unchoke peer
int select_optunchoke_peer();  // 从peer队列中选择一个优化非阻塞peer


int compute_rate();            // 计算最近一段时间(10秒)每个peer的上传下载速度
int compute_total_rate();      // 计算总的上传下载速度


int is_seed(Peer *node);       // 判断某个peer是否为种子

// 构造数据请求,为了提高效率一次请求5个slice
int create_req_slice_msg(Peer *node);  

#endif

以下是policy.c文件的头部包含:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "parse_metafile.h"
#include "peer.h"
#include "data.h"
#include "message.h"
#include "policy.h"

Unchoke_peers  unchoke_peers;// 存放非阻塞Peer和优化非阻塞Peer的指针
long long      total_down = 0L, total_up = 0L;// 总的下载量和上传量
float          total_down_rate = 0.0F, total_up_rate = 0.0F;// 总的下载上传速度
int            total_peers = 0;// 已连接的总Peer数
 
extern int	   end_mode;				// 是否已进入终端模式
extern Bitmap  *bitmap;					// 指向己方的位图
extern Peer    *peer_head;			// 指向Peer链表
extern int     pieces_length;		// 所有piece hash值的长度
extern int     piece_length;		// 每个piece的长度

extern Btcache *btcache_head;		//指向一个维护16K缓冲区的结构体
extern int     last_piece_index;//最后一个piece号
extern int     last_piece_count;//最后一个piece的slice数量
extern int     last_slice_len;	//最后下载的piece中最后的slice的大小
extern int     download_piece_num;//当前已下载的piece数量

以下是plicy.c的函数的实现:

void init_unchoke_peers()

/*
*功能:初始化全局变量unchoke_peers
*传入参数:无
*传出参数:unchoke_peers
*返回值:
*/
void init_unchoke_peers()
{
	int i;

	for(i = 0; i < UNCHOKE_COUNT; i++) 
	{//非阻塞的peer的初始化
		*(unchoke_peers.unchkpeer + i) = NULL;//初始化保存非阻塞Peer的指针	
	}

	unchoke_peers.count = 0;	//当前非阻塞的peer的个数
	unchoke_peers.optunchkpeer = NULL;//初始化保存优化非阻塞Peer的指针
}

int is_in_unchoke_peers(Peer *node)

/*
*功能:判断一个peer是否已经存在于unchoke_peers
*传入参数:peer的地址
*传出参数:
*返回值:
		1	peer非阻塞
		0	peer阻塞
*/
int is_in_unchoke_peers(Peer *node)
{
	int i;

	for(i = 0; i < unchoke_peers.count; i++) 
	{
		if( node == (unchoke_peers.unchkpeer)[i] )  
		{//比较指针中的值和参数(地址)
			return 1;
		}
	}

	return 0;
}

int get_last_index(Peer **array, int len)

/*
*功能:从unchoke_peers(指针数组)中获取下载速度最慢的peer的索引
*传入参数:peer的地址和对应的长度
*传出参数:
*返回值:
		-1   没有任何速度不存在此peer
		j	 速度
		
*/
int get_last_index(Peer **array,int len)
{
	int i, j = -1;

	if(len <= 0) 
	{
		return j;
	}
	else 
	{
		j = 0;
	}

	for(i = 0; i <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值