当前位置:首页 > 生活百科

torrent磁力种子搜索(BT磁力搜索引擎)

栏目:生活百科日期:2025-04-13浏览:0

ltsession(会话)是最核心的,种子只有加入进去方可下载上传等动作。

session_handle: 主要负责对session的操作。

torrent_handle: 主要负责对种子的操作以及状态查询。

session.pop_alerts(): 可以获取从上次调用以来的所有新警报的列表。每种特定类型的警报可能包括特定于消息类型的附加状态。所有警报都实现一个message()函数,该函数输出警报消息的相关信息。这可以方便地记录事件。

下面先针对各小功能进行代码实现,最好再整合一个完整的代码例子

1. 添加种子/磁力(并下载)

lt::session ses; //定义session对象lt::add_torrent_params p = lt::parse_magnet_uri("magnet:?xt=urn:btih:......");        // 解析磁力链接p.save_path = ".";                                     // 设置保存到当前目录lt::torrent_handle h = ses.add_torrent(p); //添加到session,并获得其句柄(该句阻塞执行,有结果才返回)
lt::session ses; //定义session对象auto ti = std::make_shared&<lt::torrent_info&>(torrentFilePath); //通过种子文件 定义 torrent_info对象lt::add_torrent_params p; p.ti = ti;//这儿很重要, 必须要中torrent_info对象传递进来p.save_path = ".";p.userdata = static_cast&<void*&>(new std::string(torrentFilePath)); //这根据自己需要而定具体数据ses.async_add_torrent(std::move(p)); //这儿是异步调用, 调完就离开,获取不到 session_handle

以上为 通过磁力链接 和 torrent 种子这两种方式添加到session的简单例子。torrent_info类又诸多构造函数,对象定义方法也因此非常多,根据需要选择合适的。

另外添加种子到session的方法有 同步调用(阻塞耗时)和异步调用(立即返回)两种,也根据需要选择。

2. 警报

直接上代码讲解

for (;;) {      std::vector&<lt::alert*&> alerts;      ses.pop_alerts(&&alerts);     //获取自上次调用以来的新警报列表      for (lt::alert const* a : alerts) {  //遍历处理自己需要的警报。          std::cout &<&< a-&>message() &<&< std::endl; //打印警报信息                   // 下面是针对各种类型的警报进行处理例子          if (lt::alert_cast&<lt::torrent_finished_alert&>(a)) {                goto done;          }          if (lt::alert_cast&<lt::torrent_error_alert&>(a)) {              goto done;          }      }      std::this_thread::sleep_for(std::chrono::milliseconds(200));}  done:  std::cout &<&< "done, shutting down" &<&< std::endl;

我们可以用‘警报掩码’抓取我们关心的警报(有很多种类),如下 :

lt::settings_pack pack;pack.set_int(lt::settings_pack::alert_mask      // 设置掩码 关心 下面三种掩码        , lt::alert::error_notification        | lt::alert::storage_notification        | lt::alert::status_notification);lt::session ses(pack);

警报掩码 之 掩码类别

警报类型

3. 更新配置选项

session启动后,可以通过调用 apply_settings() 更新配置,

lt::settings_pack pack;pack.set_int(lt::settings_pack::alert_mask,lt::alert::status_notification);  ses.apply_settings(pack);     // 更新配置 alert_mask

虽然这样可以更新配置,但有些设置最好在启动会话之前设置,比如 listen_interfaces,以避免出现竞争条件。如果使用默认设置启动会话,然后立即更改它们,则仍会有一个应用默认设置的窗口。

更改设置可能会触发侦听套接字关闭和重新打开,并发送NAT-PMP、UPnP更新。因此,将设置更新批处理到单个调用中通常是一个好主意。

4. 获取种子状态

for(;;){      ses.post_torrent_updates();   // 发送 alert::status_notification  std::this_thread::sleep_for(250);        std::vector&<lt::alert*&> alerts;      ses.pop_alerts(&&alerts);     //获取自上次调用以来的新警报列表      for (lt::alert const* a : alerts) {            //  处理 state_update_alert          if (state_update_alert* p = alert_cast&<state_update_alert&>(a)) {            // 包含自上次调用以来更新的种子状态                 std::vector&<torrent_status&> status = p-&>stauts;            ......          }      }        ....}

5. 恢复种子

恢复下载时,BT引擎必须恢复正在下载种子的状态,特别是文件的哪些部分已下载, 有两种方法可以做到这一点:

(1) 从磁盘读取已下载文件片段,并将其与预定的哈希值进行比较。

(2) 保存已下载的片段(和部分片段)的状态到磁盘,并在恢复时重新加载。

如果添加种子时没有提供恢复数据,那么libtorrent将默认使用上面第1点。

libtorrent有提供函数,实现保存恢复数据的功能:

torrent_handle.save_resume_data(torrent_handle::save_info_dict); 

调用该函数的时机:

(1). 人为地选中某个种子,操作‘保存恢复数据’。

(2). 每个种子加载完成时。

(3). 关闭session之前。

注意:调用该函数并没将恢复数据保存到磁盘上面, 调用该函数后实际上会发出警报:

save_resume_data_alert(若成功) 或
save_resume_data_failed_alert
(若失败)

else if (save_resume_data_alert* p = alert_cast&<save_resume_data_alert&>(a)){torrent_handle h = p-&>handle; // 获取torrent_handle,目的是获取torrent_statusauto const buf = write_resume_data_buf(p-&>params); // p-&>params为 add_torrent_params 类型torrent_status st = h.status(torrent_handle::query_save_path);save_file(resume_file(st.info_hash), buf); //保存恢复数据到名为info_hash(长度40)的文件中}else if (save_resume_data_failed_alert* p = alert_cast&<save_resume_data_failed_alert&>(a)){// 如果不需要保存恢复数据,可以不打印错误信息return p-&>error == lt::errors::resume_data_not_modified;}

6. session对象的析构销毁

默认情况下会话析构函数会被阻塞。关闭时,需要联系追踪器以停止种子,其他未完成的操作需要取消。关闭有时可能需要几秒钟,主要是因为跟踪器没有响应(和超时)以及DNS服务器没有响应。DNS查找在失控时尤其难以中止。

为了能够异步地开始销毁等待,可以调用session::abort()。它返回一个session_proxy对象,它是一个句柄,用于在销毁会话状态时保持会话状态。它故意不提供任何会话操作,因为它正在关闭。

拥有session_proxy对象后,会话析构函数不会阻塞。但是session_proxy析构函数却将被阻塞。

这可用于并行关闭多个会话或应用程序的其他部分。

7. 完整实例

#include &<iostream&>#include &<thread&>#include &<chrono&>#include &<fstream&>#include &<libtorrent/session.hpp&>#include &<libtorrent/add_torrent_params.hpp&>#include &<libtorrent/torrent_handle.hpp&>#include &<libtorrent/alert_types.hpp&>#include &<libtorrent/bencode.hpp&>#include &<libtorrent/torrent_status.hpp&>#include &<libtorrent/read_resume_data.hpp&>#include &<libtorrent/write_resume_data.hpp&>#include &<libtorrent/error_code.hpp&>#include &<libtorrent/magnet_uri.hpp&>using clk = std::chrono::steady_clock;//  返回 种子各种状态的名称char const* state(lt::torrent_status::state_t s){  switch(s) {    case lt::torrent_status::checking_files: return "checking";    case lt::torrent_status::downloading_metadata: return "dl metadata";    case lt::torrent_status::downloading: return "downloading";    case lt::torrent_status::finished: return "finished";    case lt::torrent_status::seeding: return "seeding";    case lt::torrent_status::allocating: return "allocating";    case lt::torrent_status::checking_resume_data: return "checking resume";    default: return "&<&>";  }}int main(int argc, char const* argv&[]) try{if (argc != 2) {      std::cerr &<&< "usage: " &<&< argv&[0] &<&< " &<magnet-url&>" &<&< std::endl;    return 1;}  lt::settings_pack pack;  pack.set_int(lt::settings_pack::alert_mask    , lt::alert::error_notification    | lt::alert::storage_notification    | lt::alert::status_notification);  lt::session ses(pack);  clk::time_point last_save_resume = clk::now();  // 从磁盘加载恢复数据,并在添加磁力链接时传递它  std::ifstream ifs(".resume_file", std::ios_base::binary);  ifs.unsetf(std::ios_base::skipws);  std::vector&<char&> buf{std::istream_iterator&<char&>(ifs) , std::istream_iterator&<char&>()};  lt::add_torrent_params p = lt::read_resume_data(buf);  lt::add_torrent_params magnet = lt::parse_magnet_uri(argv&[1]);  if (p.info_hash != magnet.info_hash) { //判断恢复数据和磁力链接是否匹配,以磁力链接为准    p = std::move(magnet);  }  p.save_path = "."; // 保存到当前目录  ses.async_add_torrent(std::move(p));  lt::torrent_handle h;  //当我们收到add_torrent_alert时,我们设置它  for (;;) {    std::vector&<lt::alert*&> alerts;    ses.pop_alerts(&&alerts);    for (lt::alert const* a : alerts) {      if (auto at = lt::alert_cast&<lt::add_torrent_alert&>(a)) {        h = at-&>handle;      }      // 如果收到 torrent_finished_alert或torrent_error_alert,则退出程序      if (lt::alert_cast&<lt::torrent_finished_alert&>(a)) {        h.save_resume_data();        goto done;      }      if (lt::alert_cast&<lt::torrent_error_alert&>(a)) {        std::cout &<&< a-&>message() &<&< std::endl;        goto done;      }      // resume data准备就绪,保存到磁盘文件      if (auto rd = lt::alert_cast&<lt::save_resume_data_alert&>(a)) {        std::ofstream of(".resume_file", std::ios_base::binary);        of.unsetf(std::ios_base::skipws);        auto const b = write_resume_data_buf(rd-&>params);        of.write(b.data(), b.size());      }      if (auto st = lt::alert_cast&<lt::state_update_alert&>(a)) {        if (st-&>status.empty()) continue;        // 因为我们只有一个种子,所以我们知道 这个status是哪个种子的        lt::torrent_status const&& s = st-&>status&[0];        std::cout &<&< "r" &<&< state(s.state) &<&< " "          &<&< (s.download_payload_rate / 1000) &<&< " kB/s "          &<&< (s.total_done / 1000) &<&< " kB ("          &<&< (s.progress_ppm / 10000) &<&< "%) downloadedx1b&[K";        std::cout.flush();      }    }    std::this_thread::sleep_for(std::chrono::milliseconds(200));    // post state_update_alert 更新种子输出状态    ses.post_torrent_updates();    // 每30秒保存恢复数据一次    if (clk::now() - last_save_resume &> std::chrono::seconds(30)) {      h.save_resume_data();      last_save_resume = clk::now();    }  }  // 理想情况下,我们应该在这里保存恢复数据done:  std::cout &<&< "ndone, shutting down" &<&< std::endl;}catch (std::exception&& e) {     std::cerr &<&< "Error: " &<&< e.what() &<&< std::endl;}

“torrent磁力种子搜索(BT磁力搜索引擎)” 的相关文章

什么是多士炉多士炉的作用是什么(SMEG多士炉使用指南及

生活中,除了诗和远方,显然还有柴米油盐!那么我们该如何将这日复一日的单调生活,过的更加有趣呢?也许我们可以从厨房下手,为生活注入艺术与情调!而这款意大利进口的S...

hr软件是什么意思(hr人力资源软件排名)

2021年国内人力资源管理系统软件排名!目前市面上的人力资源管理系统软件非常多,到底有哪些好用又靠谱呢?今天为大家整理一下国内好用的人力资源管理系统软件排名,可...

lol韩服如何注册账号(韩国ipin注册教程)

英雄联盟手游韩服账号怎么注册?英雄联盟手游已经在日本、韩国、泰国、新加坡等地开启了测试,因为国服尚未开启,部分玩家选择在韩服参与本次测试。下面就是英雄联盟手游韩...

双十一活动什么时候开始什么时候结束(双十一报名及活动

一、2020年双十一提前至11月1日开始,两波销售,“双倍快乐”2020年8月12日,阿里巴巴集团副总裁、天猫平台营运事业部总经理家洛在阿里妈妈M峰会上透露,今...

两千左右的手机排行榜(两千左右值得入手的手机推荐)

去年国内厂商对高端市场进行冲击,发布了不少旗舰机,小米更是扬言要对标iPhone。很多人认为只有旗舰手机才能有全面的配置,其实不然,在2000元-3000元价格...

icloud怎么读什么意思(1分钟了解icloud的含义)

iCloud是苹果公司为苹果用户提供的一项云存储服务,每个账号都有5GB的免费使用空间。利用iCloud,用户可以将iPhone、Mac、iPad等苹果设备上的...

pdf查看有哪些方法(pdf查看方法步骤)

经常接触各种电子文档的人对于PDF肯定特别熟悉,但对于另一部分日常更多使用office的人来说,PDF格式相对陌生,那么如何才能打开PDF文件查看呢?打开PDF...

凉菜加盟品牌有哪些(推荐这6款凉菜加盟品牌)

卤味作为遗传了几千年的一种口味,是人类基因自然选择后的结果,是一种让人上瘾且不会腻的味道。卤制品一路走来,踩得最正确的点,就是确定休闲小吃的定位,将卤味真正从正...

如何选择手机品牌,选择手机的基本知识

我国目前的手机市场上不乏一些优秀的手机,而这些手机的价格确实也不便宜,基本都在5000+,所以想要购买高端旗舰手机,就必须比别人做更多的功课,毕竟选错了手机,损...

java的面向对象特征(java中对象的概念)

一、面向对象概述浅谈java面向对象1、面向对象介绍java是一门面向对象的语言,在java里一切皆对象。(1)面向过程和面向对象面向过程——步骤化面向过程就是...