Python实现DHT协议无法接收公共节点响应求助
Python实现DHT协议无法获取公共节点响应的问题排查与修复
问题情况
- 用Python实现DHT的
get_peers请求时,始终无法从公共节点router.bittorrent.com:6881收到响应,但相同逻辑的Node.js版本可正常获取响应 - 已尝试关闭Windows防火墙、将Socket绑定到
0.0.0.0、在Kali Linux虚拟机测试,问题均未解决
代码核心错误分析
你的代码存在一个关键问题:生成的my_id是字符串类型,而非DHT协议要求的字节串类型。
DHT协议规定所有请求数据需通过bencode编码,其中节点ID必须是20字节的原始字节序列。你的rand函数返回的是Python字符串对象,bencode处理时会将其按UTF-8编码转换为字节,这会导致最终发送的请求格式不符合协议规范,公共节点无法解析该请求,因此不会返回响应。
修复后的代码
import socket import random import bencoding # info_hash 是字节串参数 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.settimeout(3) network_info = (socket.gethostbyname('router.bittorrent.com'), 6881) # 修改:直接生成字节串类型的20字节节点ID rand_id = lambda: bytes([random.randint(0, 255) for _ in range(20)]) my_id = rand_id() get_peers = { b"t": b'aa', b"y": b"q", b"q": b"get_peers", b"a": { b"id": my_id, b"info_hash": info_hash } } encoded_data = bencoding.encode(get_peers) # 使用sendto更贴合UDP无连接特性,也可保留原connect后用send sock.sendto(encoded_data, network_info) try: res = sock.recv(1024) print("收到响应:", bencoding.decode(res)) except socket.timeout: print("请求超时")
额外排查建议
- 确认使用的bencoding库能正确处理字节串,避免使用对字符串编码逻辑有差异的库
- 用抓包工具(如Wireshark)对比Python和Node.js发送的UDP数据包,验证编码后的请求格式是否一致
- 尝试更换其他公共DHT节点测试,比如
router.utorrent.com:6881或dht.transmissionbt.com:6881,排除单个节点故障可能
内容的提问来源于stack exchange,提问作者user13820346
相关产品推荐
相关产品推荐

