使用winsock spi在WSPSend函数中修改http请求头时遇到问题,怎么样给lpBuffers重新赋值

谢邀。我不是很熟悉WinSocks(工作需要,网络部分我大部分时间在UNIX环境下)。所以我的解释可能是错误的。同等专家解答。从原本的初始分析上看,楼主的理解是正确的。我猜你的代码是用的异步WinSock?这种情况比较常见。如果是异步WinSock,那么应该是在两种方法中选择一个:或者是在lpOverlapped参数中通过hEvent来让系统在操作结束时触发事件;或者通过WSPSend()的倒数第三个参数,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine 来指定一个回调函数在操作完成之后处理释放问题。两种应该都是可以的。另外一点是我看到MSDN中提到了一个我从未用过的WPUQuqueApc()函数。但是我不熟悉它的用法,也就很难给出有用的建议。还是建议用上面的两个方法解决吧。http://msdn.microsoft.com/en-us/library/windows/desktop/ms742292(v=vs.85).aspx
■网友
题目有点老,题主提这个问题是由于当时是初学,对C/C++编程的内存管理还不熟悉。相信题主早已解决此问题,不过既然看到,还是来填个坑。比起.NET,C/C++的最大灵活之处就是能够灵活管理内存,所以必须约定好什么时候由什么人分配与释放内存。个人并不建议初学者就去依赖泄漏检查工具,内存管理约定是在C/C++设计初期就应该考虑的问题。内存管理的一般约定是主张“谁分配谁释放”,C库函数(如malloc/free,new/delete)由于引用只对本模块有效的隐式声明的堆而必须保证对上述函数的成对调用必须限制在本模块(dll)里。如果设计是多模块的,必须要跨模块释放,则操作内存必须直接调用由kernel32提供的HeapAlloc与HeapFree。以该问题为例,windows申请的内存只能windows去释放,你要写的lsp模块申请的内存必须你自己释放。所以当你尝试delete windows的内存肯定会assert,而你自己分配的new header没有释放当然就泄漏了。显然在send的挂钩里你没有机会释放这段内存了。一般来想是应该放在调用上级的send后释放,但这个尝试你实验失败了,大概是由于异步的原因。那么标准的方案应该是记录所有的异步请求与你分配的buffer的映射,手动轮询请求是否完成,将完成的请求用到的buffer释放掉。不建议使用lpCompletionRoutine与event,因为你这是钩子函数,这些参数有可能是应用程序已经定好的,改起来不方便。


    推荐阅读