如何使用btdht获取对等端客户端名称及版本信息
问题描述
我用示例代码能正常运行,但代码只显示对等端(peer)的IP和端口。我想获取对等端的客户端名称及版本,比如Transmission 4.0这类信息。相关文档已有说明,但我不知道怎么用。试过用ChatGPT生成代码,但代码完全无法运行。
示例代码:
>>> import btdht >>> import binascii >>> dht = btdht.DHT() >>> dht.start() # now wait at least 15s for the dht to boostrap init socket for 4c323257aa6c4c5c6ccae118db93ccce5bb05d92 Bootstraping >>> dht.get_peers(binascii.a2b_hex("0403fb4728bd788fbcb67e87d6feb241ef38c75a")) [ ('81.171.107.75', 17744), ('94.242.250.86', 3813), ('88.175.164.228', 32428), ('82.224.107.213', 61667), ('85.56.118.178', 6881), ('78.196.28.4', 38379), ('82.251.140.70', 32529), ('78.198.108.3', 10088), ('78.235.153.136', 10619), ('88.189.113.32', 33192), ('81.57.9.183', 5514), ('82.251.17.155', 14721), ('88.168.207.178', 31466), ('82.238.89.236', 32970), ('78.226.209.88', 2881), ('5.164.219.48', 6881), ('78.225.252.39', 31002) ]
解决方案
要获取对等端的客户端名称和版本,需要用到btdht.krcp模块实现的KRCP协议——这是BitTorrent网络中用于查询peer元数据的协议,能返回客户端标识等信息。
步骤说明:
- 导入KRCP客户端:从
btdht.krcp导入KRCP类。 - 初始化KRCP实例:创建KRCP客户端对象,可指定本地端口(默认自动分配)。
- 遍历DHT获取的peer列表:对每个IP和端口,调用KRCP的
query方法获取元数据。 - 解析客户端标识:从返回的元数据中提取
client字段,通过前缀映射表转换为可读的客户端名称和版本。
完整示例代码:
import btdht import binascii from btdht.krcp import KRCP import time # 初始化DHT并启动 dht = btdht.DHT() dht.start() print("等待DHT引导完成(至少15秒)...") time.sleep(15) # 获取目标torrent的peer列表 info_hash = binascii.a2b_hex("0403fb4728bd788fbcb67e87d6feb241ef38c75a") peers = dht.get_peers(info_hash) print(f"获取到{len(peers)}个对等端") # 初始化KRCP客户端 krcp = KRCP() # 常见BitTorrent客户端的peer ID前缀映射表 client_mapping = { "TR": "Transmission", "UT": "µTorrent", "QT": "qBittorrent", "AZ": "Azureus", "ST": "BitSpirit", "SB": "Shareaza", "WD": "WebTorrent" # 可根据需求补充更多客户端前缀 } # 逐个查询peer的客户端信息 for ip, port in peers: try: # 发送KRCP查询,设置2秒超时 metadata = krcp.query(ip, port, timeout=2) if metadata and "client" in metadata: client_id = metadata["client"] # 拆分前缀和版本号 prefix = client_id[:2] version = client_id[2:] if len(client_id) > 2 else "未知版本" client_name = client_mapping.get(prefix, f"未知客户端({prefix})") print(f"IP: {ip}:{port} | 客户端: {client_name} {version}") else: print(f"IP: {ip}:{port} | 无法获取客户端信息") except Exception as e: print(f"IP: {ip}:{port} | 查询失败: {str(e)}") # 停止DHT和KRCP服务 dht.stop() krcp.stop()
注意事项:
- 必须等待DHT完全引导完成(至少15秒),否则获取的peer列表可能为空或不完整。
- KRCP查询易受网络影响,需设置合理超时时间避免阻塞。
- 客户端前缀映射表可根据实际遇到的peer ID补充,覆盖更多客户端类型。
内容的提问来源于stack exchange,提问作者user3595893
相关产品推荐
相关产品推荐

