BT下载的协议与接口

研究了一段时间的libtorrent,苦于对boostasio的了解很有限,一直都没研究它的核发心部分……

为了增加士气,只好从外围好懂一点的模块着手研究……

torrent_info模块我觉得libtorrent做得很好。因为它可以方便地生成或者读取一个.torrent的信息,而不像bittorrent源码那些,读取.torrent是靠bencode/bdecode,生成.torrent却靠另外一个模块。在python读取bencode结构很方便,在C++中读取却很繁琐。torrent_info可以使libtorrent库用户无需了解太多相关的知识而可以实现BT协议,不知不说它真的做得比较好。还有将它们合并在一起,增加了模块的内聚性。另外它还提供了piece和文件位置的映射功能。

torrent_ifno接借了如下接口
要说明一下的是entry,一个entry代表的是一个bencode的一个结点。

 

 

 

classtorrent_info
{
public:
       
torrent_info();
       
torrent_info(sha1_hashconst&info_hash);
       
torrent_info(entryconst&torrent_file);//从一个文件取读数据后,经过bdecode函数转换成entry,之再转输入到这里

       
entry create_torrent()const;//根据本对象现存的信息,每成一个entry对象

       
voidset_comment(charconst* str);//设置注释

       
voidset_piece_size(intsize);//设置piece大小

       
voidset_creator(charconst* str);//设置创建程序名称

       
voidset_hash(intindex, sha1_hash const& h);//设置某一piece的SHA-1 digest

       
voidadd_tracker(std::stringconst& url,int tier = 0);//添加tracker服务器,tier代表优先级,0最高

       
voidadd_file(boost::filesystem::path file,size_type size);//添加一个文件信息

       
voidadd_url_seed(std::stringconst& url);//添加一个url seed地址


       
typedefstd::vector<file_entry>::const_iterator file_iterator;
       
typedefstd::vector<file_entry>::const_reverse_iterator
 
               reverse_file_iterator;

       
file_iterator begin_files()const;//返回文件信息的迭代器

       
file_iterator end_files()const;
        
reverse_file_iteratorrbegin_files()const;//返回文件信息的逆向迭代器

       
reverse_file_iterator rend_files()const;

 
      int num_files()const;//返回文件数量

       
file_entry const& file_at(int index)const;//根据文件信息录入的序号返回文件信息


       
std::vector<file_slice>map_block(intpiece,size_type offset
               
,intsize)const;//??

       
peer_request map_file(int file_index,size_type file_offset
               
,intsize)const;//??


       
std::vector<announce_entry>const& trackers()const;//返回tracker列表


       
std::vector<std::string>const& url_seeds()const;//返回url seed 列表


       
size_typetotal_size()const;//返回所有文件大小的总和

       
size_typepiece_length()const;//返回piece长度

       
intnum_pieces()const;//返回piece数量

       
sha1_hash const& info_hash()const;//返回.torrent的info_hash

       
std::stringconst& name()const;//返回.torrent的name

       
std::stringconst&comment()const;//返回注释

       
std::stringconst&creator()const;//返回创建程序名称

       
boost::optional<boost::posix_time::ptime>
       
creation_date()const;//返回创建时间

       
voidprint(std::ostream& os)const;//输出所有信息到标准输出流


       
size_typepiece_size(unsignedint index)const;//返回指定piece的大小,只有最后一个piece的大小不同于其它piece

       
sha1_hash const& hash_for_piece(unsignedint index)const;//返回指定piece的SHA-1hash

};


要用代码说明torrent_info如何使用,最好的代码莫过于libtorrent的例子make_torrent.cpp

#include<iostream>
#include<fstream>
#include<iterator>
#include<iomanip>

#include"libtorrent/entry.hpp"
#include"libtorrent/bencode.hpp"
#include"libtorrent/torrent_info.hpp"
#include"libtorrent/file.hpp"
#include"libtorrent/storage.hpp"
#include"libtorrent/hasher.hpp"
#include"libtorrent/file_pool.hpp"

#include<boost/filesystem/operations.hpp>
#include<boost/filesystem/path.hpp>
#include<boost/filesystem/fstream.hpp>

usingnamespace boost::filesystem;
usingnamespace libtorrent;

void add_files(
   
torrent_info& t
   
, path const& p
   
, path const& l)
{
   
if(l.leaf()[0]=='.')return;
   
path f(p /l);
   
if(is_directory(f))
   
{
       
for(directory_iteratori(f), end; i != end;++i)
           
add_files(t,p, l / i->leaf());
   
}
   
else
   
{
       
std::cerr<<"adding\""<< l.string()<<"\"\n";
       
t.add_file(l,file_size(f));
   
}
}


int main(intargc,char*argv[])
{
   
usingnamespace libtorrent;
   
usingnamespace boost::filesystem;

   
path::default_name_check(no_check);

   
if(argc!= 4 && argc != 5)
   
{

       
return 1;
   
}

   
try
   
{
       
torrent_info t;
       
path full_path =complete(path(argv[3]));
       
ofstream out(complete(path(argv[1])),std::ios_base::binary);

       
intpiece_size = 256 * 1024;
       
charconst* creator_str ="libtorrent";

       
add_files(t,full_path.branch_path(),full_path.leaf());
       
t.set_piece_size(piece_size);

       
file_pool fp;
       
storage st(t,full_path.branch_path(), fp);
       
t.add_tracker(argv[2]);

       
// calculate the hash for all pieces

       
int num =t.num_pieces();
       
std::vector<char> buf(piece_size);
       
for(int i = 0; i < num;++i)
       
{
           
st.read(&buf[0], i, 0, t.piece_size(i));
           
hasher h(&buf[0], t.piece_size(i));
           
t.set_hash(i,h.final());
           
std::cerr<<(i+1)<<"/"<< num <<"\r";
       
}

       
t.set_creator(creator_str);

       
if(argc== 5)
           
t.add_url_seed(argv[4]);

       
// create the torrent and print it to out

       
entry e = t.create_torrent();
       
libtorrent::bencode(std::ostream_iterator<char>(out), e);
   
}
   
catch(std::exception& e)
   
{
       
std::cerr<< e.what()<<"\n";
   
}

   
return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值