首页 > 解决方案 > 当我尝试使用跟踪器 URL 建立连接请求时,socket.recv() 超时

问题描述

我正在尝试了解种子是如何工作的,并编写了一个 python 脚本来向跟踪器 URL 发送连接请求并得到一些响应。我按照协议准备了连接消息,并使用sock.send()方法发送了它,带有ip和端口(检查get_peers_list功能,它的功能不完整,因为我卡在了连接请求部分)。我收到超时错误,无法继续前进。这是我的脚本:

from bcoding import bdecode, bencode
import time, hashlib
from urllib.parse import urlparse
import socket 
import random
from struct import pack, unpack

def load_from_path(path):
    with open(path, 'rb') as file:
        contents = bdecode(file)

    #random seed to generate peer_id
    seed = str(time.time())

    return {
        "torrent_file": contents,
        "piece_length": contents['info']['piece length'],
        "pieces": contents['info']['pieces'],
        "info_hash": hashlib.sha1( bencode(contents['info']) ).digest(),
        "peer_id": hashlib.sha1(seed.encode('utf-8')).digest(),
        "announce": contents['announce'] 
    }

class UdpTrackerConnection():
    def __init__(self):
        self.conn_id = pack('>Q', 0x41727101980)
        self.action = pack('>I', 0)
        self.trans_id = pack('>I', random.randint(0, 100000))

    def to_bytes(self):
        return self.conn_id + self.action + self.trans_id

    def from_bytes(self, payload):
        self.action, = unpack('>I', payload[:4])
        self.trans_id, = unpack('>I', payload[4:8])
        self.conn_id, = unpack('>Q', payload[8:])

def _read_from_socket(sock):
    data = b''

    while True:
        try:
            buff = sock.recv(4096)
            print("got some response", buff)
            if len(buff) <= 0:
                break

            data += buff
        except socket.error as e:
            print(e)
            break
        except Exception:
            print("Recv failed")
            break

    return data

def get_peers_list(torrent):
    parsed = urlparse(torrent['announce'])
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.settimeout(4)
    ip, port = socket.gethostbyname(parsed.hostname), parsed.port
    tracker_connection_input = UdpTrackerConnection()
    message = tracker_connection_input.to_bytes()
    sock.sendto(message, (ip, port))
    try:
        response = _read_from_socket(sock)
    except socket.timeout as e:
        print("Timeout : %s" % e)
        return
    except Exception as e:
        print("Unexpected error when sending message : %s" % e.__str__())
        return
    tracker_connection_output = UdpTrackerConnection()



path_to_torrent = "test.torrent"
torrent = load_from_path(path_to_torrent)
get_peers_list(torrent)

我得到这个输出

got some response b'\x00\x00\x00\x00\x00\x00\xe2\x9b{E\xf0U\xfb\x9b\xf2\xc6'
timed out

我对这里的套接字很陌生,任何帮助都会很好。

标签: pythonbittorrent

解决方案


你有一个字节串,你需要像这样将每个字节转换成它的整数等价物。

>>> mt = b'\x00\x00\x00\x00
>>> intg = list(b)
>>> intg
[0, 0, 0, 0]

文档可能会对您有所帮助。


推荐阅读