看到网上也有开源的代码,这不,我拿来进行了二次重写,呵呵,上代码:

#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", 6881),

("dht.transmissionbt", 6881),

("router.utorrent", 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:</