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

WinHTTP异步回调context无效、WinHttpReceiveResponse返回错误码6求助

问题根因分析
  • context字段取值异常的核心原因:你使用std::vector<connection_context>存储上下文对象,std::vector在动态扩容时会重新分配整块内存,原有存储元素的内存地址会全部失效。你调用WinHttpSendRequest时传入的是&contexts.back()这个临时地址,后续循环继续push_back触发扩容后,之前传给WinHTTP的所有context指针全部指向无效内存,自然读取不到正确的字段值。
  • 错误码6(无效句柄)的核心原因:connection_context结构体中的read_complete事件句柄没有初始化,你没有调用CreateEvent创建事件对象,WaitForSingleObject会立刻返回错误,代码直接执行WinHttpCloseHandle(contexts[i].request_handle)关闭请求句柄。此时异步回调才开始执行,访问已经被关闭的request_handle自然触发无效句柄错误。
修复方案
  1. 解决context地址失效问题:
    方案一:预先给vector分配足够容量,避免运行时扩容:在循环前调用contexts.reserve(ggs_get_aobs.size())
    方案二:改用std::list<connection_context>存储上下文,list的元素插入删除不会改变原有元素的内存地址
    方案三:使用堆分配存储context:每个上下文用new connection_context创建,等请求完全结束后再delete释放,避免内存泄漏
  2. 初始化事件句柄:
    每个connection_context对象创建时,添加初始化逻辑:
    contexts.back().read_complete = CreateEvent(NULL, FALSE, FALSE, NULL);
    
    所有请求处理完成后,调用CloseHandle释放事件句柄,避免句柄泄漏
  3. 调整资源释放逻辑:
    不要在WaitForSingleObject返回后立刻关闭请求句柄,建议增加请求完成标记,确认所有回调逻辑执行完毕后再释放请求句柄、context等资源,避免回调执行时访问已经释放的资源
  4. 请求体传参优化:
    WinHttpSendRequest的请求体长度参数不需要+1,直接传入contexts.back().request_payload.size()即可,额外多传的\0会被当成请求体的一部分发送给服务端,可能导致服务端解析异常。

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 00:00:01