以下代碼利用libtorrent實現了BT客戶端程序,需要包含boost庫和libtorrent庫
具體使用如下:
ltclient.exe e:\5DE0513D406C65FEA074E39CD4B98A7F16816C86.torrent e:\download\xyz\
exe + torrent + savepath
// ltclient.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//
#include "pch.h"
#include <iostream>
#include "libtorrent\entry.hpp"
#include "libtorrent\bencode.hpp"
#include "libtorrent\session.hpp"
#include "libtorrent\torrent_info.hpp"
#include <libtorrent\alert_types.hpp>
#include <libtorrent\torrent_status.hpp>
#include <chrono>
using namespace std;
using namespace chrono;
static int count;
INT64 downloadsize = 0;
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 "<>";
}
}
// return the name of a torrent status enum
bool handle_alter(lt::session& ses, lt::alert* a, lt::torrent_handle &th)
{
using namespace lt;
if (add_torrent_alert *p = alert_cast<add_torrent_alert>(a))
{
if (p->error)
{
std::fprintf(stderr, "failed to add torrent:%s %s\n"
,p->params.ti?p->params.ti->name().c_str():p->params.name.c_str()
,p->error.message().c_str());
}
}
else if (torrent_finished_alert *p = alert_cast<torrent_finished_alert>(a))
{
cout << "torrent finished" << endl;
}
else if (state_update_alert *p = alert_cast<state_update_alert>(a))
{
char cinfo[1024] = { 0x00 };
std::vector<std::int64_t> file_progress;
th.file_progress(file_progress); // 獲取文件下載進度
int const idx = static_cast<int>(0);
if(!p->status.empty())
{
lt::torrent_status s = th.status(lt::torrent_handle::query_save_path);
//lt::torrent_status s = p->status[0];//如果只有一個torrent文件,就直接取status[0]
//sprintf_s(cinfo, sizeof(cinfo), "%s download rate %dKB /s, total_download %dKB, uprate %dKB /s, total_up %dKB, progress %.1lf, progress_ppm %lld progress %lld%% %d%%"
//, state(s.state),s.download_payload_rate/1000, s.total_done/1000, s.upload_rate/1000, s.total_upload/1000, s.progress, s.progress_ppm, int(s.progress_ppm/10000), file_progress[0]*100 / downloadsize);
cout << state(s.state) << " download rate " << s.download_payload_rate / 1000 << "KB /s, total_download " << s.total_done / 1000 << "KB, uprate " << s.upload_rate / 1000 << "KB /s, total_up " << s.total_upload / 1000
<< "KB, progress " << s.progress << " progress_ppm " << s.progress_ppm << " progress " << s.progress_ppm / 10000 << " " << file_progress[0] * 100 / downloadsize << endl;
//sprintf_s(cinfo, "%s download rate %dKB /s, total_download %dKB, uprate %dKB /s, total_up %dKB, curdown %lld, filesize %lld, downprogress %lld%%"
// , state(s.state), s.download_payload_rate / 1000, s.total_done / 1000, s.upload_rate / 1000, s.total_upload / 1000, file_progress[0], downloadsize, file_progress[0] * 100 / downloadsize);
cout << cinfo << endl;
std::cout.flush();
//lt::torrent_status st = th.status(lt::torrent_handle::query_save_path);
//std::cout << "\r" << state(st.state) << " "
// << (st.download_payload_rate / 1000) << " kB/s "
// << (st.total_done / 1000) << " kB ("
// << (st.progress_ppm / 10000) << "%) downloaded";
//std::cout.flush();
}
}
return true;
}
int suxy(int x, int y);
int main(int argc, char ** argv)
try
{
cout << ::count << endl;
if (argc < 3)
{
std::cerr << "uage: ltclient torrent-file path\n";
return 1;
}
int nTimedOut = 2000; //設置下載超時時間
std::string save_path(".\\");//保存文件路徑
int torrent_upload_limit = 100000 * 1000; //上傳速度限制
int torrent_download_limit = 100000*1000; //下載速度限制 單位是字節
//BT下載客戶端代碼
lt::settings_pack pack;
pack.set_int(lt::settings_pack::alert_mask
, lt::alert::error_notification
| lt::alert::storage_notification
| lt::alert::status_notification);
pack.set_str(lt::settings_pack::user_agent, "ltclient/""test");
lt::session ses(pack);
//設置下載參數
lt::add_torrent_params params;
//params.save_path = save_path;
params.save_path = argv[2];
params.ti = std::make_shared<lt::torrent_info>(argv[1]);
params.download_limit = torrent_download_limit;
params.upload_limit = torrent_upload_limit;
auto start = system_clock::now();
lt::torrent_handle th = ses.add_torrent(params);
static auto end = system_clock::now();
static auto duration = duration_cast<microseconds>(end - start);;
while (true)
{
//*************************************************************************
//std::thread printprogress([&ses,th]
//{
// lt::torrent_status st = th.status(lt::torrent_handle::query_save_path);
// std::cout << "\r" << state(st.state) << " "
// << (st.download_payload_rate / 1000) << " kB/s "
// << (st.total_done / 1000) << " kB ("
// << (st.progress_ppm / 10000) << "%) downloaded";
// std::cout.flush();
//});
//
//printprogress.join();
//***********************************************************************
downloadsize = params.ti->files().file_size(0); //下載文件的總大小
std::vector<lt::alert*> alerts;
ses.pop_alerts(&alerts);
for (auto a : alerts)
{
//if (::handle_alter(ses, a, th))
//{
// continue;
//}
::handle_alter(ses, a, th);
}
std::vector<std::int64_t> file_progress;
th.file_progress(file_progress); // 獲取文件下載進度
int const idx = static_cast<int>(0);
bool const complete = file_progress[idx] == downloadsize; //判斷文件是否下載完成
if (complete)
{
ses.post_torrent_updates();
cout << "\ndownload is complete" << endl;
break;
}
end = system_clock::now();
duration = duration_cast<microseconds>(end - start);
if ((double(duration.count())*microseconds::period::num / microseconds::period::den) > 100 && file_progress[idx] == 0)
{
cout << "download failed,check" << endl;
break;
}
if ((double(duration.count())*microseconds::period::num / microseconds::period::den) > nTimedOut)//判斷是否超時
{
cout << "download timed out" << endl;
break;
}
//std::this_thread::sleep_for(std::chrono::microseconds(3000));
ses.post_torrent_updates();
}
std::string title = params.ti->files().file_name(0).to_string();
cout << "download "<<title<<" cost " << double(duration.count())*microseconds::period::num / microseconds::period::den<<"s"<<endl;
while (1)
{
char c = getchar();
if (c == 'p')
break;
}
return 0;
}
catch (std::exception const &e) {
std::cerr << "ERROR: " << e.what() << "\n";
}
// 運行程序: Ctrl + F5 或調試 >“開始執行(不調試)”菜單
// 調試程序: F5 或調試 >“開始調試”菜單
// 入門提示:
// 1. 使用解決方案資源管理器窗口添加/管理文件
// 2. 使用團隊資源管理器窗口連接到源代碼管理
// 3. 使用輸出窗口查看生成輸出和其他消息
// 4. 使用錯誤列表窗口查看錯誤
// 5. 轉到“項目”>“添加新項”以創建新的代碼文件,或轉到“項目”>“添加現有項”以將現有代碼文件添加到項目
// 6. 將來,若要再次打開此項目,請轉到“文件”>“打開”>“項目”並選擇 .sln 文件
源碼附帶庫文件: