基于BT协议的libtorrent研究与应用开发分析

2012-05-08 04:41杨青周冬梅王一飞
电脑知识与技术 2012年7期
关键词:键值哈希数据结构

杨青 周冬梅 王一飞

摘要:首先介绍了BT元信息文件及BT库libtorrent的数据交互过程,然后对libtorrent的部分重要数据结构进行了分析与说明,提出了业务插件扩展的使用方法。

关键词:BT协议;libtorrent应用;BT插件

中图分类号:TP393文献标识码:A文章编号:1009-3044(2012)07-1526-03

Analysis of Libtorrent s Application Based on BT Protocol

YANG Qing, ZHOU Dong- mei ,WANG Yi-fei

(College of Science and Technology, Chengdu University of Technology, Chengdu 610059, China)

Abstract: Firstly,introduced the bt element information file and bt-libtorrents interactive process.Secondly,analyzed some important data structure of libtorrent. Lastly,put forward the method of using plug-in extension of business.

Key words: BT protocol; libtorrent App; BT plug-in

在现今网络通信中,BT作为p2p技术的一种已得到广泛应用。在开源的BT协议库中,LibTorrent是C++语言BitTorrent开发库,旨在提供高性能和良好代码风格的BT开发包。该开发包与其他包不同的是,它直接通过网络堆栈抓取文件页,其性能是官方客户端的数倍,尤其在基于服务器的bt服务器端开发中颇为重要。

1 BT元信息文件

元信息文件(Metainfo File Structure)又称为种子文件(.torrent),其结构元信息文件里面的所有数据都是一个以B编码的dictionary,包含下面列出的重要的键(key):

1) info键对应的值为一字典(dictonary),描述要发布的文件信息,分单文件模式和多文件模式,其中共有键piece length的键值为每片(piece)的字节数(通常情况下2的n次方),共有键pieces的键值是所有片(piece)哈希值字符串,如piece0:hash0 piece1:hash1。

2) announce的键值为tracher服务器的URL地址。

2 libtorrent数据交互

在peer的交互中,客户端首先向Tracker请求下载,同时包括本地资源的发布,服务器端Tracker响应则包含客户端请求的资源列表。

2.1 Peer客户端的TRACKER请求报文(announce)

TRACKER请求报文(announce)的重要参数主要有:表示为元信息文件中的info键值(20字节哈希值)、表示为客户端唯一ID的Peer_id、监听端口、客户端uploaded情况、客户端download情况和客户端IP地址。

2.2 Tracker响应报文(text/plain)

响应文本由B编码的字典(dictionary)组成,其中failure reason的键值表示可读的错误信息。Complete为完成整个文件下载的peer数以及peers键值为一个字典列表(peer的id、ip、port)。

2.3 Peer与Peer的交互过程

Peer与Peer的交互需要经过握手,piece信息的发布以及piece的请求等过程,如图1所示。

值得注意的是on_bitfield必须在handshake后立即发送,如peer无任何已下载了的piece也可以不发送bitfield。但在peer间通讯的其他时候不再允许发送此消息。

3 Libtorrent库解析

libtorrent库的接口由少量几个类组成。最主要的类有session、entry、torrent_info、torrent_handle、alert、extensions。其内部工作流程为如图2所示。

图1 Peer与Peer的交互过程示意图

图2 libtorrent内部工作流程

3.1重要的数据结构

3.1.1 entry类

在编码体系结构中,代表一个节点时可使用entry类。它可以是某个变量类型:链表(list)、字典(dictionary)、整数(integer)或者字符串(string等其中成员函数integer()、string()、list()、dict()函数是返回相应类型的生产者。find_key()将在字典里查找指定关键字的元素,如从torrent信息文件中获得信息的常用代码:

dictionary_typeconst& dict = torrent_file.dict();

dictionary_type::const_iterator i=dict.find("announce");

if(i != dict.end()) {

std::string tracker_url = i->second.string();

std::cout << tracker_url << std::endl;}

3.1.2 torrent_info类

从torrent_info类中可以更快的从torrent信息文件中获取信息,其中有懒惰接入对象的构造函数将会从给定任务文件的信息中创建torrent_info对象。懒惰参数接入对象代表了编码文件中的树节点。为了加载一个.torrent文件到一个懒惰接入对象中去,可以使用lazy_bdecode(), bdecode(), bencode()。值得一提的是含有一个哈希信息的构造函数可用来初始化哈希信息,当没有元数据(metadata)或种子文件及无种下载时,这个将会内部使用,一旦元数据从群中下载,libtorrent将创建metadata。

3.1.3 torrent_handle类

对于管理单个事物,libtorrent提供了torrent_handle类来实现管理,如获取torrent信息,自动管理,上传、下载设置,涉及的函数有

set_torrent_info()、save_resume_data()、auto_managed()、pause(),resume()、set_max_connections()、set_upload_limit(t)、set_download_limit()等。

其中save_resume_data(),可将一些状态信息、资源下载情况等保存到指定文件(xx.resume)中,以便需要时能够快速的恢复到之前的状态继续下载。

3.1.4 alert_manager类

告警是反应系统运行情况的一重要窗口,alert_manager::post_alert(const alert &alert)是从库中获得警告、消息、错误的接口。如果队列中没有警告,post_alert()将返回一个默认的初始化auto_ptr对象,否则将最前面的警告返回。通过session::set_alert_mask()用来指定哪类事件将被报告。如alert::error_notification(激活报告错误的警告)、alert::peer_notification(对等点发送了非法请求,禁用,或没有上传或者下载时抛警告)、alert::progress_notification(块被请求或者完成时警告)等.

在实际应用开发中,特定的任务的警告都从alert类上面继承,在libtorrent中提供了丰富的警告或错误处理接口类,以及提供了进行管理和处理的方式,如:

std::auto_ptr a = ses.pop_alert();

while(alert *pAlert = a.get()){

if(torrent_finished_alert *pfinished =

alert_cast(pAlert))

{ .....

torrent_handle h = pfinished ->handle;h.save_resmue_data();

}

if(save_resume_data_alert*pResume=

alert_cast(pAlert))

{

torrent_handle h = p->handle;

......

std::cout<<"save resume data,name:"<

}

a = ses.pop_alert();

}

3.2业务插件的扩展

扩展是libtorrent的一大重要特点,整个代码的设计优良,其为业务扩展提供了便利。void add_extension(boost::function(torrent*, void*)> ext)函数的参数是个函数对象,且其参数是一任务指针,应用时通过add_extension()函数来添加扩展插件,如create_ut_metadata_plugin能够提供元数据(metadata)以及peer交互扩展。插件接口由两部分组成:torrent_plugin类和peer_plugin类,例如要设计一个特殊功能的插件special_function_plugin流程如下:

struct special_function_plugin: torrent_plugin {

重载相关成员函数(如on_files_checked(),on_piece_pass(),on_piece_failed()等};

struct special_function_peer_plugin: peer_plugin{

重载相关成员函数(如on_handshake(),on_extension_handshake(),on_bitfield(),on_piece(),on_suggest()等};

boost::shared_ptr special_function_plugin::new_connection(peer_connection* pc)

{bt_peer_connection *c

=dynamic_cast(pc);

if(!c) return boost::shared_ptr();

return boost::shared_ptr(new special_function_peer_plugin(m_torrent,*c, *this));}

4結束语

分析了bt协议的交互过程及交互中涉及的重要参数。同时对libtorrent的部分重要数据结构进行了简要分析与说明,并给出了libtorrent的内部工作流程。对于重要的数据结构的使用提供部分伪代码,提出了插件扩展的使用方法,为快速的理解、使用libtorrent进行开发提供了参考。

参考文献:

[1] libtorrent document[EB/OL].http://libtorrent.rakshasa.no.

[2] bittorrent document [EB/OL].http://www.bittorrent.com/.

[3] bit protocol[EB/OL].http://www.bittorrent.com/.

猜你喜欢
键值哈希数据结构
“翻转课堂”教学模式的探讨——以《数据结构》课程教学为例
基于OpenCV与均值哈希算法的人脸相似识别系统
基于维度分解的哈希多维快速流分类算法
TRIZ理论在“数据结构”多媒体教学中的应用
基于同态哈希函数的云数据完整性验证算法
《数据结构》教学方法创新探讨
一种基于Bigram二级哈希的中文索引结构
注册表值被删除导致文件夹选项成空白
“扫除”技巧之清除恶意程序