用python进行libtorrent开发实践

编译libtorrent的python bindings

安装环境

sudo apt-get install python-dev
sudo apt-get install build-essential
sudo apt-get install libboost-all-dev 
sudo apt-get install libssl-dev

再下载源码编译

wget "https://github.com/arvidn/libtorrent/releases/download/libtorrent-1_1_6/libtorrent-rasterbar-1.1.6.tar.gz"
tar vxzf libtorrent-rasterbar-1.1.6.tar.gz
cd libtorrent-rasterbar-1.1.6/
./configure --enable-python-binding
make -j2

最后生成需要的三个so文件在

bindings/python/build/lib.linux-x86_64-2.7/libtorrent.so
src/.libs/libtorrent-rasterbar.so
src/.libs/libtorrent-rasterbar.so.9
src/.libs/libtorrent-rasterbar.so.9.0.0

把这三个so(其中前两个是软链,连接到最后一个文件)放到一个文件夹比如 /home/kyle/libtorrent

然后设置环境变量 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/kyle/libtorrent

之后直接在python中 import libtorrent 就可以了。

做种

假设我有两个文件 1.mp4 1.txt ,存放在目录 /home/kyle/bt/seed/ 下面,需要做种。那么生成种子文件的示例代码如下

import sys
import os
import libtorrent
import time

dir_path = '/home/kyle/bt/seed' # 下面有两个文件 1.mp4 1.txt
fs = libtorrent.file_storage()
libtorrent.add_files(fs, dir_path)
torrent = libtorrent.create_torrent(fs, 0, 4 * 1024 * 1024)
# 使用一个tracker server,也可以自己搭建一个server
torrent.add_tracker("http://tracker.opentrackr.org:1337/announce")
torrent.set_creator('libtorrent %s' % libtorrent.version)
parent_dir = os.path.dirname(dir_path)
libtorrent.set_piece_hashes(torrent, parent_dir, lambda x: sys.stderr.write(str(x)))
raw = torrent.generate()
print ''
# 生成磁力链接
print libtorrent.make_magnet_uri(libtorrent.torrent_info(raw))
with open("/home/kyle/bt/1.torrent", "wb") as f:
    f.write(libtorrent.bencode(raw))

其中add_tracker方法添加的tracker服务器,可以从网上找可用的,也可以自己搭建。

网上找的话,这里有一些 tracker server 列表:https://github.com/ngosang/trackerslist

自己搭建 tracker server ,可以用开源软件: https://github.com/chihaya/chihaya

或者其它的, Comparison of BitTorrent tracker software: https://en.wikipedia.org/wiki/Comparison_of_BitTorrent_tracker_software

下载文件

通过种子文件下载的示例代码如下

import sys
import os
import libtorrent
import time

session = libtorrent.session()
session.set_alert_queue_size_limit(1024 * 1024)
session.listen_on(6881, 6881)
torrent_info = libtorrent.torrent_info('/home/kyle/bt/1.torrent')
add_params = {
    'save_path': '/home/kyle/bt/',
    'storage_mode': libtorrent.storage_mode_t.storage_mode_sparse,
    'paused': False,
    'auto_managed': True,
    'ti': torrent_info,
    # 如果是磁力链接,就用 url 替代 ti 参数
    # 'url': 'magnet:?xt=urn:btih:69bda373e8e3e0c59428bfb90c5df8c50603d751&tr=udp://9.rarbg.to:2710/announce',
}
handle = session.add_torrent(add_params)
session.start_dht()

alert = session.pop_alert()
while alert:
    print '[alert msg]: %s' % alert.message()
    alert = session.pop_alert()
state_str = ['queued', 'checking', 'downloading metadata', \
            'downloading', 'finished', 'seeding', 'allocating', 'checking fastresume']

# 阻塞下载
while not (handle.is_seed()):
    s = handle.status()
    print '\ractive_time: %d, %.2f%% complete (down: %.1f kb/s up: %.1f kB/s peers: %d, seeds: %d) %s' % \
            (s.active_time, s.progress * 100, s.download_rate / 1000, s.upload_rate / 1000, \
            s.num_peers, s.num_seeds, state_str[s.state]),
    sys.stdout.flush()
    time.sleep(0.2)
# 下载完后开始做种
handle.super_seeding()

# 阻塞输出做种状态
seedtime = 1000
while seedtime > 0:
    seedtime -= 1
    s = handle.status()
    print '\rseed_time: %d, %.2f%% complete (down: %.1f kb/s up: %.1f kB/s peers: %d, seeds: %d) %s' % \
            (s.active_time, s.progress * 100, s.download_rate / 1000, s.upload_rate / 1000, \
            s.num_peers, s.num_seeds, state_str[s.state]),
    sys.stdout.flush()
    time.sleep(1)

如果第一次下载,就在生成种子的同一台机器上,则save_path参数设置成做种文件的目录,那么下载很快1-2秒就完成了,然后本机就进入做种状态。

这时候在其它机器上打开BT下载软件,如迅雷,deluge等,就可以正常下载。或者运行上面的代码进行下载。

参考

python实现p2p文件传输—适用大文件传输: http://www.361way.com/python-p2p/4737.html

Converting a Magnet Link into a Torrent:http://danfolkes.com/2012/04/19/converting-a-magnet-link-into-a-torrent/

libtorrent reference documentation:https://libtorrent.org/reference.html

Build libtorrent from source:http://dev.deluge-torrent.org/wiki/Building/libtorrent