看到网上也有开源的代码,这不,我拿来进行了二次重写,呵呵,上代码:
#encoding: utf-8
import socket
from hashlib import sha1
from random import randint
from struct import unpack, pack
from socket import inet_aton, inet_ntoa
from bisect import bisect_left
from threading import Timer
from time import sleep
import MySQLdb
from datetime import *
import time
from bencode import bencode, bdecode
BOOTSTRAP_NODES = [
("router.bittorrent.com", 6881),
("dht.transmissionbt.com", 6881),
("router.utorrent.com", 6881)
]
TID_LENGTH = 4
KRPC_TIMEOUT = 10
REBORN_TIME = 5 * 60
K = 8
def entropy(bytes):
s = ""
for i in range(bytes):
s += chr(randint(0, 255))
return s
def random_id():
hash = sha1()
hash.update( entropy(20) )
return hash.digest()
def decode_nodes(nodes):
n = []
length = len(nodes)
if (length % 26) != 0:
return n
for i in range(0, length, 26):
nid = nodes[i:i+20]
ip = inet_ntoa(nodes[i+20:i+24])
port = unpack("!H", nodes[i+24:i+26])[0]
n.append( (nid, ip, port) )
return n
def encode_nodes(nodes):
strings = []
for node in nodes:
s = "%s%s%s" % (node.nid, inet_aton(node.ip), pack("!H", node.port))
strings.append(s)
return "".join(strings)
def intify(hstr):
return long(hstr.encode('hex'), 16)
def timer(t, f):
Timer(t, f).start()
class BucketFull(Exception):
pass
class KRPC(object):
def __init__(self):
self.types = {
"r": self.response_received,
"q": self.query_received
}
self.actions = {
"ping": self.ping_received,
"find_node": self.find_node_received,
"get_peers": self.get_peers_received,
"announce_peer": self.announce_peer_received,
}
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.socket.bind(("0.0.0.0", self.port))
def response_received(self, msg, address):
self.find_node_handler(msg)
def query_received(self, msg, address):
try:
self.actions[msg["q"]](msg, address)
except KeyError:
pass
def send_krpc(self, msg, ad