如何短时间滞留出站数据包以模拟网络延迟?
解决pydivert模拟游戏网络延迟时的网络冻结问题
你写的代码会导致整个网络卡死,核心问题有两个:
- 过滤规则太宽泛:
"outbound"会拦截所有出站数据包,包括浏览器、聊天软件等所有程序的流量,一旦处理不及时就会堵死整个网络。 - 单线程阻塞处理:
time.sleep(0.005)在主线程执行,意味着每次处理一个包时,后续所有数据包都得等待sleep结束才能被接收和发送,直接导致整个出站流量停滞。
改进方案
1. 缩小过滤范围,只拦截游戏流量
把过滤规则改成针对游戏的IP或端口,比如假设游戏服务器IP是192.168.1.100,或者游戏用的端口是8080,过滤规则可以这么写:
# 只拦截发往游戏服务器的TCP出站包 w_outbound = WinDivert("outbound and tcp.DstAddr = 192.168.1.100") # 或者按端口过滤 # w_outbound = WinDivert("outbound and tcp.DstPort = 8080")
这样只会延迟游戏的流量,其他程序的网络不受影响。
2. 用多线程处理延迟,避免主线程阻塞
把延迟发送的逻辑放到单独线程里,主线程只负责快速接收数据包,不耽误后续包的处理:
from pydivert import WinDivert import time import threading def delay_send(packet, divert_handle): time.sleep(0.005) # 模拟5ms延迟 divert_handle.send(packet) # 替换成你的游戏目标IP/端口 w_outbound = WinDivert("outbound and tcp.DstAddr = 192.168.1.100") w_outbound.open() try: while True: packet = w_outbound.recv() # 启动新线程处理延迟发送,主线程继续接收下一个包 threading.Thread(target=delay_send, args=(packet, w_outbound), daemon=True).start() except KeyboardInterrupt: w_outbound.close() # 记得关闭句柄
额外注意事项
- 运行脚本需要管理员权限,否则pydivert无法拦截网络包。
- 如果延迟太高或者线程太多,可能会导致数据包丢失,根据实际测试调整sleep的时间。
- 测试完成后一定要用
Ctrl+C终止脚本,或者确保程序退出时调用w_outbound.close(),避免残留的网络拦截导致异常。
内容的提问来源于stack exchange,提问作者WellINeedHelpRn
相关产品推荐
相关产品推荐

