杨青 周冬梅 王一飞
摘要:首先介绍了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
while(alert *pAlert = a.get()){
if(torrent_finished_alert *pfinished =
alert_cast
{ .....
torrent_handle h = pfinished ->handle;h.save_resmue_data();
}
if(save_resume_data_alert*pResume=
alert_cast
{
torrent_handle h = p->handle;
......
std::cout<<"save resume data,name:"< } a = ses.pop_alert(); } 3.2业务插件的扩展 扩展是libtorrent的一大重要特点,整个代码的设计优良,其为业务扩展提供了便利。void add_extension(boost::function 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 {bt_peer_connection *c =dynamic_cast if(!c) return boost::shared_ptr return boost::shared_ptr 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/.