我正在开发一个使用事件驱动的winsock套接字的http客户端。 但是我对如何处理FD_CLOSE消息感到困惑。 在某些情况下,我会收到FD_CLOSE,即使强硬,仍然有数据要在套接字中读取。 所以我现在的代码是这样的:
WSAEventSelect(s,hevent,FD_READ | FD_WRITE | FD_CLOSE); while (1) { WaitForSingleEvent(hevent,TIMEOUT); WSAEnumNetworkEvents(s,hevent,&netevent); if ((netevent.lNetworkEvents & FD_READ) || (netevent.lNetworkEvents & FD_CLOSE)) { do { resrecv=recv(s,buf,sizeof(buf),0); if (resrecv<0) throw "recv failed"; if (resrecv==0) break; /* Handle the message here. */ } while (netevents.lNetworkEvents & FD_CLOSE); } /* Write response to the socket. (If we received all of the request) */ if (netevent.lNetworkEvents & FD_CLOSE) { closesocket(s); break; } }
它基本上读取尽可能多的数据,一旦收到FD_CLOSE。 但是当它收到一个FD_READ时,它只发出一个recv。 这种方法似乎工作到目前为止,但它看起来很奇怪,尤其是在做的部分。 而且我恐怕这将在未来的某个时候变成越野车。 什么是处理FD_CLOSE的正确方法? 在MSDN或Windows SDK中找不到任何示例。
(我在上面的代码片段中省略了一些明显的错误检查。)
编辑:这里有两个演示程序可以用来观察这种行为:
下载代码