python实现的一个p2p文件传输实例
考虑到我手上的服务器逐渐的增多,有时候需要大规模的部署同一个文件,例如因为方便使用systemtap这个工具定位问题,需要把手上几百台服务器同时安装kernel-debuginfo这个包,原有的方式采用一个源服务器,采用rsync或者scp之类的文件传输方式只能做到一个点往下分发这个文件,这个时候下发的速度就会比较的慢,基于以上原因,我写了一个基于bt协议传输文件的小工具,实际测试,传输到10个机房,70多台机器传输一个240M的这个内核文件,到所有的机器,源采用限速2m/s的上传速度,测试的结果大概只要140s,就可以全部传输完毕,这个效率是非常之高,如果不限速的情况下速度会更快,下面把这个程序开源出来。
代码如下:
#!/usr/bin/env python
import libtorrent as lt
import sys
import os
import time
from optparse import OptionParser
import socket
import struct
import fcntl
def get_interface_ip(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s',
ifname[:15]))[20:24])
def ip2long(ip):
return reduce(lambda a,b:(a
def get_wan_ip_address():
interfaces = set(['eth0', 'eth1', 'eth2', 'eth3', 'em1', 'em2', 'em3', 'em4'])
ip = ''
for i in interfaces:
try:
ip = get_interface_ip(i)
if (ip2long(ip) ip2long('10.255.255.255')) \
and (ip2long(ip) ip2long('172.33.255.255')) \
and (ip2long(ip) ip2long('192.168.255.255')):
return ip
except:
pass
return ip
def make_torrent(path, save):
fs = lt.file_storage()
lt.add_files(fs, path)
if fs.num_files() == 0:
print 'no files added'
sys.exit(1)
input = os.path.abspath(path)
basename = os.path.basename(path)
t = lt.create_torrent(fs, 0, 4 * 1024 * 1024)
t.add_tracker("http://10.0.1.5:8760/announce")
t.set_creator('libtorrent %s' % lt.version)
lt.set_piece_hashes(t, os.path.split(input)[0], lambda x: sys.stderr.write('.'))
sys.stderr.write('\n')
save = os.path.dirname(input)
save = "%s/%s.torrent" % (save, basename)
f=open(save, "wb")
f.write(lt.bencode(t.generate()))
f.close()
print "the bt torrent file is store at %s" % save
def dl_status(handle):
while not (handle.is_seed()):
s = handle.status()
state_str = ['queued', 'checking', 'downloading metadata', \
'downloading', 'finished', 'seeding', 'allocating', 'checking fastresume']
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(1)
def seed_status(handle, seedtime=100):
seedtime = int(seedtime)
if seedtime seedtime = 100
while seedtime > 0:
seedtime -= 1
s = handle.status()
state_str = ['queued', 'checking', 'downloading metadata', \
'downloading', 'finished', 'seeding', 'allocating', 'checking fastresume']
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)
def remove_torrents(torrent, session):
session.remove_torrent(torrent)
def read_alerts(session):
alert = session.pop_alert()
while alert:
#print alert, alert.message()
alert = session.pop_alert()
def download(torrent, path, upload_rate_limit=0, seedtime=100):
try:
session = lt.session()
session.set_alert_queue_size_limit(1024 * 1024)
sts = lt.session_settings()
sts.ssl_listen = False
sts.user_agent = "Thunder deploy system"
sts.tracker_completion_timeout = 5
sts.tracker_receive_timeout = 5
sts.stop_tracker_timeout = 5
sts.active_downloads = -1
sts.active_seeds = -1
sts.active_limit = -1
sts.auto_scrape_min_interval = 5
sts.udp_tracker_token_expiry = 120
sts.min_announce_interval = 1
sts.inactivity_timeout = 60
sts.connection_speed = 10
sts.allow_multiple_connections_per_ip = True
sts.max_out_request_queue = 128
sts.request_queue_size = 3
sts.use_read_cache = False
session.set_settings(sts)
session.set_alert_mask(lt.alert.category_t.tracker_notification | lt.alert.category_t.status_notification)
session.set_alert_mask(lt.alert.category_t.status_notification)
ipaddr = get_wan_ip_address()
#print ipaddr
if ipaddr == "":
session.listen_on(6881, 6881)
else:
session.listen_on(6881, 6881, ipaddr)
limit = int(upload_rate_limit)
if limit>=100:
session.set_upload_rate_limit(limit*1024)
session.set_local_upload_rate_limit(limit*1024)
print session.upload_rate_limit()
torrent_info = lt.torrent_info(torrent)
add_params = {
'save_path': path,
'storage_mode': lt.storage_mode_t.storage_mode_sparse,
'paused': False,
'auto_managed': True,
'ti': torrent_info,
}
handle = session.add_torrent(add_params)
read_alerts(session)
st = time.time()
dl_status(handle)
et = time.time() - st
print '\nall file download in %.2f\nstart to seeding\n' % et
sys.stdout.write('\n')
handle.super_seeding()
seed_status(handle, seedtime)
remove_torrents(handle, session)
assert len(session.get_torrents()) == 0
finally:
print 'download finished'
if __name__ == '__main__':
usage = "usage: %prog [options] \n \
%prog -d -f
or \n \
%prog -m -p
parser = OptionParser(usage=usage)
parser.add_option("-d", "--download", dest="download",
help="start to download file", action="store_false", default=True)
parser.add_option("-f", "--file", dest="file",
help="torrent file")
parser.add_option("-u", "--upload", dest="upload",
help="set upload rate limit, default is not limit", default=0)
parser.add_option("-t", "--time", dest="time",
help="set seed time, default is 100s", default=100)
parser.add_option("-p", "--path", dest="path",
help="to make torrent with this path")
parser.add_option("-m", "--make", dest="make",
help="make torrent", action="store_false", default=True)
parser.add_option("-s", "--save", dest="save",
help="file save path, default is store to ./", default="./")
(options, args) = parser.parse_args()
#download(sys.argv[1])
if len(sys.argv) != 6 and len(sys.argv) != 4 and len(sys.argv) != 8 and len(sys.argv) != 10:
parser.print_help()
sys.exit()
if options.download == False and options.file !="":
download(options.file, options.save, options.upload, options.time)
elif options.make == False and options.path != "":
make_torrent(options.path, options.save)
准备环境:
需要在所有的os上面安装一个libtorrent的库,下载地址:
http://code.google.com/p/libtorrent/downloads/list
记得编译的时候带上./configure –enable-python-binding,然后mak,make install,进入binding目录,make,make install就
可以运行这个小的工具
当然大规模部署不可能采用每一台都去编译安装的方式,只要把编译出来的libtorrent.so libtorrent-rasterbar.so.7的文件跟bt.py这个文件放到同一个目录,另外写一个shell脚本
代码如下:
lib=`dirname $0`
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$lib
python bt.py -d -f -s -t -u
使用方法:
首先在源服务器上面生成种子文件
代码如下:
python bt.py -m -p -s
发布文件
在源服务器上面,执行
代码如下:
python bt.py -d -f -s -t -u
其中做种时间默认设置的是100s,上传速度默认不限制,限制的速度单位是KB
下面的机器,直接可以
代码如下:
python bt.py -d -f -s -t
只要有一台机器完成了,就自动作为种子,在下载的过程中也会上传,任何一台机器都可以作为源服务器,当然了这里面还有中心的tracker服务器,脚本当中,我搭建了一个tracker源服务器,放到10.0.1.5端口是8760上面,当然大家也可以采用opentracker这个软件自己搭建一个tracker服务器,修改其中的源代码对应部分,另外考虑到发布都是私有文件,代码当作已经禁止了dht,如果还想更安全,就自己搭建一个私有的tracker server,具体搭建方法就使用一下搜索引擎,查找一下搭建的方法!
目前基本做到可以使用,后续考虑更简单一点,采用磁力链接的方式,这样就可以做到不用每台都要拷贝一个种子文件,采用一个单独的命令行就可以发布整个文件

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











XML을 PDF로 직접 변환하는 응용 프로그램은 근본적으로 다른 두 형식이므로 찾을 수 없습니다. XML은 데이터를 저장하는 데 사용되는 반면 PDF는 문서를 표시하는 데 사용됩니다. 변환을 완료하려면 Python 및 ReportLab과 같은 프로그래밍 언어 및 라이브러리를 사용하여 XML 데이터를 구문 분석하고 PDF 문서를 생성 할 수 있습니다.

모바일 XML에서 PDF의 속도는 다음 요인에 따라 다릅니다. XML 구조의 복잡성. 모바일 하드웨어 구성 변환 방법 (라이브러리, 알고리즘) 코드 품질 최적화 방법 (효율적인 라이브러리 선택, 알고리즘 최적화, 캐시 데이터 및 다중 스레딩 사용). 전반적으로 절대적인 답변은 없으며 특정 상황에 따라 최적화해야합니다.

단일 애플리케이션으로 휴대 전화에서 직접 XML에서 PDF 변환을 완료하는 것은 불가능합니다. 두 단계를 통해 달성 할 수있는 클라우드 서비스를 사용해야합니다. 1. 클라우드에서 XML을 PDF로 변환하십시오. 2. 휴대 전화에서 변환 된 PDF 파일에 액세스하거나 다운로드하십시오.

XML을 통해 이미지를 생성하려면 XML에서 메타 데이터 (크기, 색상)를 기반으로 이미지를 생성하기 위해 브리지로 그래프 라이브러리 (예 : Pillow 및 JFreeChart)를 사용해야합니다. 이미지의 크기를 제어하는 열쇠는 & lt; width & gt의 값을 조정하는 것입니다. 및 & lt; 높이 & gt; XML의 태그. 그러나 실제 애플리케이션에서 XML 구조의 복잡성, 그래프 드로잉의 편향, 이미지 생성 속도 및 메모리 소비 및 이미지 형식 선택은 모두 생성 된 이미지 크기에 영향을 미칩니다. 따라서 그래픽 라이브러리에 능숙한 XML 구조에 대한 깊은 이해가 필요하고 최적화 알고리즘 및 이미지 형식 선택과 같은 요소를 고려해야합니다.

XML 서식 도구는 규칙에 따라 코드를 입력하여 가독성과 이해를 향상시킬 수 있습니다. 도구를 선택할 때는 사용자 정의 기능, 특수 상황 처리, 성능 및 사용 편의성에주의하십시오. 일반적으로 사용되는 도구 유형에는 온라인 도구, IDE 플러그인 및 명령 줄 도구가 포함됩니다.

C 언어에는 내장 합계 기능이 없으므로 직접 작성해야합니다. 합계는 배열 및 축적 요소를 가로 질러 달성 할 수 있습니다. 루프 버전 : 루프 및 배열 길이를 사용하여 계산됩니다. 포인터 버전 : 포인터를 사용하여 배열 요소를 가리키며 효율적인 합계는 자체 증가 포인터를 통해 달성됩니다. 동적으로 배열 버전을 할당 : 배열을 동적으로 할당하고 메모리를 직접 관리하여 메모리 누출을 방지하기 위해 할당 된 메모리가 해제되도록합니다.

대부분의 텍스트 편집기를 사용하여 XML 파일을여십시오. 보다 직관적 인 트리 디스플레이가 필요한 경우 Oxygen XML 편집기 또는 XMLSPy와 같은 XML 편집기를 사용할 수 있습니다. 프로그램에서 XML 데이터를 처리하는 경우 프로그래밍 언어 (예 : Python) 및 XML 라이브러 (예 : XML.etree.elementtree)를 사용하여 구문 분석해야합니다.

XML 구조가 유연하고 다양하기 때문에 모든 XML 파일을 PDF로 변환 할 수있는 앱은 없습니다. XML에서 PDF의 핵심은 데이터 구조를 페이지 레이아웃으로 변환하는 것입니다. XML을 구문 분석하고 PDF를 생성해야합니다. 일반적인 방법으로는 요소 트리와 같은 파이썬 라이브러리를 사용한 XML 및 ReportLab 라이브러리를 사용하여 PDF를 생성하는 XML을 구문 분석합니다. 복잡한 XML의 경우 XSLT 변환 구조를 사용해야 할 수도 있습니다. 성능을 최적화 할 때는 멀티 스레드 또는 멀티 프로세스 사용을 고려하고 적절한 라이브러리를 선택하십시오.
