Win10下WinDivert报错997:TCP三次握手及RST包规避方案咨询
解决WinDivert错误997(重叠I/O操作正在进行中)的排查方案
这种WinDivert错误997的问题我之前做网络路由项目时也碰到过好几次,结合你描述的情况——旧版本突然失效、重启驱动后WinDivertOpen正常但WinDivertSend/WinDivertSendEx仍报错,咱们可以从这几个核心方向排查解决:
1. 重叠I/O上下文未正确重置或清理
WinDivert底层依赖Windows的重叠I/O模型,如果之前的I/O操作(比如上一次的发送/接收请求)没有完全完成,或者对应的OVERLAPPED结构体被重复使用但未重置,就会触发这个冲突错误。尤其是旧版本之前正常现在失效,大概率是系统或进程残留了未完成的I/O请求。
- 修复步骤:
- 每次调用
WinDivertSend/WinDivertSendEx前,务必用ZeroMemory(&overlapped, sizeof(OVERLAPPED))重置OVERLAPPED结构体,绝对不要复用还在等待完成的结构体。 - 关闭WinDivert句柄时,先调用
CancelIoEx终止所有关联的未完成I/O请求,再执行WinDivertClose,避免驱动端残留无效请求。
- 每次调用
2. 驱动服务未彻底重置
有时候单纯重启电脑并没有完全清理WinDivert驱动的内部状态,比如驱动的I/O队列里还积压着未处理的请求,导致新进程调用发送接口时触发冲突。
- 修复步骤:
- 用管理员权限打开命令提示符,执行以下命令彻底重启驱动服务:
sc stop WinDivert sc start WinDivert - 用Process Explorer或类似工具检查是否有其他进程在使用
WinDivert.sys,如果有,关闭这些进程后再测试——多个进程共享WinDivert驱动时,很容易出现I/O操作冲突。
- 用管理员权限打开命令提示符,执行以下命令彻底重启驱动服务:
3. 异步I/O的同步逻辑存在漏洞
如果你的代码中使用了异步I/O模式,但没有正确等待前一次操作完成就发起新的请求,比如调用WinDivertSend后立刻再次调用,或者没有用GetOverlappedResult/WaitForSingleObject确认操作结束,就会触发错误997。
- 修复示例:
确保每次发送操作都等待完成后再继续:
如果是批量发送场景,要为每个请求分配独立的OVERLAPPED overlapped = {0}; BOOL result = WinDivertSend(divertHandle, packetBuffer, packetLength, NULL, &overlapped); if (!result) { DWORD err = GetLastError(); if (err == ERROR_IO_PENDING) { DWORD bytesSent; // 等待异步操作完成,第二个TRUE表示阻塞等待 GetOverlappedResult(divertHandle, &overlapped, &bytesSent, TRUE); } else { // 处理其他错误 printf("WinDivertSend failed with error: %d\n", err); } }OVERLAPPED结构体,不要共用一个。
4. 系统更新导致的兼容性问题
最近的Windows系统更新可能修改了网络栈的行为,或者旧版本的WinDivert驱动与新系统组件不兼容,导致原本正常的代码失效。
- 修复步骤:
- 下载WinDivert的最新稳定版本,替换项目中的驱动文件(
WinDivert.sys)和静态库/动态库,重新编译项目后测试。 - 检查WinDivert的官方文档,确认是否有针对你当前Windows版本的适配注意事项。
- 下载WinDivert的最新稳定版本,替换项目中的驱动文件(
内容的提问来源于stack exchange,提问作者ThisIsNotMyThirdAccount




