You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 01:46:08