最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python實(shí)現(xiàn)的一個(gè)p2p文件傳輸實(shí)例

 更新時(shí)間:2014年06月04日 10:19:28   投稿:junjie  
這篇文章主要介紹了python實(shí)現(xiàn)的一個(gè)p2p文件傳輸實(shí)例,文中用來(lái)解決多臺(tái)服務(wù)器維護(hù)文件同步問題,需要的朋友可以參考下

考慮到我手上的服務(wù)器逐漸的增多,有時(shí)候需要大規(guī)模的部署同一個(gè)文件,例如因?yàn)榉奖闶褂胹ystemtap這個(gè)工具定位問題,需要把手上幾百臺(tái)服務(wù)器同時(shí)安裝kernel-debuginfo這個(gè)包,原有的方式采用一個(gè)源服務(wù)器,采用rsync或者scp之類的文件傳輸方式只能做到一個(gè)點(diǎn)往下分發(fā)這個(gè)文件,這個(gè)時(shí)候下發(fā)的速度就會(huì)比較的慢,基于以上原因,我寫了一個(gè)基于bt協(xié)議傳輸文件的小工具,實(shí)際測(cè)試,傳輸?shù)?0個(gè)機(jī)房,70多臺(tái)機(jī)器傳輸一個(gè)240M的這個(gè)內(nèi)核文件,到所有的機(jī)器,源采用限速2m/s的上傳速度,測(cè)試的結(jié)果大概只要140s,就可以全部傳輸完畢,這個(gè)效率是非常之高,如果不限速的情況下速度會(huì)更快,下面把這個(gè)程序開源出來(lái)。

#!/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<<8)+b,[int(i) for i in ip.split('.')])
 
 
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.0.0.0') or ip2long(ip) > ip2long('10.255.255.255')) \
        and (ip2long(ip) < ip2long('172.16.0.0') or ip2long(ip) > ip2long('172.33.255.255')) \
        and (ip2long(ip) < ip2long('192.168.0.0') or 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 < 100:
    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 <torrent file=""> -s <file save="" path="">\n \
   or \n \
   %prog -m -p <file or="" dir=""> -s <torrent save="" path="">\n"
 
  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)
</torrent></file></file></torrent>

準(zhǔn)備環(huán)境:
需要在所有的os上面安裝一個(gè)libtorrent的庫(kù),下載地址:

http://code.google.com/p/libtorrent/downloads/list

記得編譯的時(shí)候帶上./configure –enable-python-binding,然后mak,make install,進(jìn)入binding目錄,make,make install就
可以運(yùn)行這個(gè)小的工具
當(dāng)然大規(guī)模部署不可能采用每一臺(tái)都去編譯安裝的方式,只要把編譯出來(lái)的libtorrent.so libtorrent-rasterbar.so.7的文件跟bt.py這個(gè)文件放到同一個(gè)目錄,另外寫一個(gè)shell腳本

復(fù)制代碼 代碼如下:
lib=`dirname $0`
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$lib
python bt.py -d -f <種子文件> -s <文件保存路徑> -t <做種時(shí)間> -u <限制上傳速度>

使用方法:
首先在源服務(wù)器上面生成種子文件

復(fù)制代碼 代碼如下:
python bt.py -m -p <要發(fā)布的文件或者文件夾> -s <種子保存地址>

發(fā)布文件
在源服務(wù)器上面,執(zhí)行
復(fù)制代碼 代碼如下:
python bt.py -d -f <種子文件> -s <文件保存路徑> -t <做種時(shí)間> -u <限制上傳速度>

其中做種時(shí)間默認(rèn)設(shè)置的是100s,上傳速度默認(rèn)不限制,限制的速度單位是KB

下面的機(jī)器,直接可以

復(fù)制代碼 代碼如下:
python bt.py -d -f <種子文件> -s <文件保存路徑> -t <做種時(shí)間>

只要有一臺(tái)機(jī)器完成了,就自動(dòng)作為種子,在下載的過(guò)程中也會(huì)上傳,任何一臺(tái)機(jī)器都可以作為源服務(wù)器,當(dāng)然了這里面還有中心的tracker服務(wù)器,腳本當(dāng)中,我搭建了一個(gè)tracker源服務(wù)器,放到10.0.1.5端口是8760上面,當(dāng)然大家也可以采用opentracker這個(gè)軟件自己搭建一個(gè)tracker服務(wù)器,修改其中的源代碼對(duì)應(yīng)部分,另外考慮到發(fā)布都是私有文件,代碼當(dāng)作已經(jīng)禁止了dht,如果還想更安全,就自己搭建一個(gè)私有的tracker server,具體搭建方法就使用一下搜索引擎,查找一下搭建的方法!

目前基本做到可以使用,后續(xù)考慮更簡(jiǎn)單一點(diǎn),采用磁力鏈接的方式,這樣就可以做到不用每臺(tái)都要拷貝一個(gè)種子文件,采用一個(gè)單獨(dú)的命令行就可以發(fā)布整個(gè)文件

相關(guān)文章

  • 使用python實(shí)現(xiàn)哈希表、字典、集合操作

    使用python實(shí)現(xiàn)哈希表、字典、集合操作

    這篇文章主要介紹了使用python實(shí)現(xiàn)哈希表、字典、集合操作,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-12-12
  • python+playwright微軟自動(dòng)化工具的使用

    python+playwright微軟自動(dòng)化工具的使用

    這篇文章主要介紹了python+playwright微軟自動(dòng)化工具的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • 一篇文章教你掌握python數(shù)據(jù)類型的底層實(shí)現(xiàn)

    一篇文章教你掌握python數(shù)據(jù)類型的底層實(shí)現(xiàn)

    這篇文章主要介紹了Python 數(shù)據(jù)類型的底層實(shí)現(xiàn)原理分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-09-09
  • Python如何實(shí)現(xiàn)轉(zhuǎn)換URL詳解

    Python如何實(shí)現(xiàn)轉(zhuǎn)換URL詳解

    這篇文章主要介紹了Python如何實(shí)現(xiàn)轉(zhuǎn)換URL詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • Python實(shí)現(xiàn)多張圖片合成一張馬賽克圖片

    Python實(shí)現(xiàn)多張圖片合成一張馬賽克圖片

    這篇文章主要介紹了了Python如何實(shí)現(xiàn)將多張圖片合成一張馬賽克圖片。文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Python有一定的幫助,感興趣的可以學(xué)習(xí)一下
    2021-12-12
  • 使用Python對(duì)網(wǎng)易云歌單數(shù)據(jù)分析及可視化

    使用Python對(duì)網(wǎng)易云歌單數(shù)據(jù)分析及可視化

    這篇文章主要介紹了使用Python對(duì)網(wǎng)易云歌單數(shù)據(jù)分析及可視化,本項(xiàng)目以數(shù)據(jù)采集、處理、分析及數(shù)據(jù)可視化為項(xiàng)目流程,需要的朋友可以參考下
    2023-03-03
  • Python3多進(jìn)程 multiprocessing 模塊實(shí)例詳解

    Python3多進(jìn)程 multiprocessing 模塊實(shí)例詳解

    這篇文章主要介紹了Python3多進(jìn)程 multiprocessing 模塊,結(jié)合實(shí)例形式詳細(xì)分析了Python3多進(jìn)程 multiprocessing 模塊的概念、原理、相關(guān)方法使用技巧與注意事項(xiàng),需要的朋友可以參考下
    2018-06-06
  • Python裝飾器使用你可能不知道的幾種姿勢(shì)

    Python裝飾器使用你可能不知道的幾種姿勢(shì)

    這篇文章主要給大家介紹了關(guān)于Python裝飾器使用你可能不知道的幾種姿勢(shì),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • python requests完成接口文件上傳的案例

    python requests完成接口文件上傳的案例

    這篇文章主要介紹了python requests完成接口文件上傳的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-03-03
  • 淺談python中列表、字符串、字典的常用操作

    淺談python中列表、字符串、字典的常用操作

    下面小編就為大家?guī)?lái)一篇淺談python中列表、字符串、字典的常用操作。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09

最新評(píng)論

凯里市| 龙海市| 麻江县| 新邵县| 明溪县| 荃湾区| 大邑县| 咸阳市| 托克逊县| 江孜县| 逊克县| 中牟县| 洪洞县| 蒙阴县| 资中县| 林西县| 巴里| 循化| 马尔康县| 宁强县| 高陵县| 三亚市| 驻马店市| 绵阳市| 比如县| 夹江县| 汉寿县| 蓝山县| 白山市| 江孜县| 宜黄县| 五寨县| 股票| 揭西县| 集贤县| 格尔木市| 同仁县| 工布江达县| 岗巴县| 吴江市| 重庆市|