- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
在我的套接字服务器中,我使用 WSAEventSelect() 和 WSAEnumNetworkEvents() 来检测 FD_ACCEPT 和 FD_CLOSE 事件。
这是我的代码的简化版本:
HANDLE sockEv=CreateEvent(NULL,TRUE,FALSE,NULL);
WSAEventSelect(servSocket,sockEv,FD_ACCEPT|FD_CLOSE);
for(;;) {
if(WSAWaitForMultipleEvents(1,&sockEv,FALSE,INFINITE,FALSE)==WSA_WAIT_EVENT_0) {
WSANETWORKEVENTS wsaEvents={0};
WSAEnumNetworkEvents(servSocket,sockEv,&wsaEvents);
if((wsaEvents.lNetworkEvents & FD_ACCEPT)==FD_ACCEPT) {
SOCKET clntSock=accept(servSocket,(sockaddr*)clientAddr,&addrlen);
....
}
else if (wsaEvents.lNetworkEvents==0) {
// this event occurs after each FD_ACCEPT event
}
....
}
....
}
问题是每次从客户端接受新连接时,我都会收到 2 个事件:首先将 WSANETWORKEVENTS.lNetworkEvents 设置为 FD_ACCEP,然后将 WSANETWORKEVENTS.lNetworkEvents 设置为零。也就是说,每次接受新客户端时,for(;;) 循环都会执行 2 次。或者 sockEv 在检测到 FD_ACCEPT 后未被 WSAEnumNetworkEvents 重置。
这个零事件是什么意思,为什么会发生?我没有在文档中找到任何关于它的信息。
更新:可编译示例
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2),&wsaData);
try {
SOCKET servSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
sockaddr_in serv={0};
serv.sin_family=AF_INET;
serv.sin_addr.s_addr=htonl(INADDR_ANY);
serv.sin_port=htons(18081);
memset(serv.sin_zero,0,sizeof(serv.sin_zero));
if(bind(servSocket,(sockaddr*)&serv,sizeof(serv))==SOCKET_ERROR)
throw WSAGetLastError();
if(listen(servSocket,SOMAXCONN)==SOCKET_ERROR)
throw WSAGetLastError();
HANDLE sockEv=CreateEvent(NULL,TRUE,FALSE,NULL);
if(WSAEventSelect(servSocket,sockEv,FD_ACCEPT|FD_CLOSE)==SOCKET_ERROR)
throw WSAGetLastError();
for(;;) {
if(WSAWaitForMultipleEvents(1,&sockEv,FALSE,INFINITE,FALSE)!=WSA_WAIT_EVENT_0)
throw -1;
WSANETWORKEVENTS wsaEvents={0};
if(WSAEnumNetworkEvents(servSocket,sockEv,&wsaEvents)==SOCKET_ERROR)
throw WSAGetLastError();
if((wsaEvents.lNetworkEvents & FD_ACCEPT)==FD_ACCEPT) {
SOCKET clntSocket=accept(servSocket,0,0);
closesocket(clntSocket);
puts("accept");
}
else if(wsaEvents.lNetworkEvents==0) {
puts("zero event");
}
}
}
catch(int errorCode) {
printf("Last Error: %d\n",errorCode);
}
WSACleanup();
return 0;
}
我在 WinXP 32 位上试过这段代码。
最佳答案
回答我自己的问题。看来我找到了发生这种情况的原因和时间。此零事件发生在客户端套接字(由 accept() 返回的套接字)关闭之后。如果您不将 FD_CLOSE 与 WSAEventSelect 一起使用,则不会发生这种情况。所以可以忽略它。MSDN 对这种行为只字不提。
关于windows - WSAEventSelect,零事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12268811/
在我的套接字服务器中,我使用 WSAEventSelect() 和 WSAEnumNetworkEvents() 来检测 FD_ACCEPT 和 FD_CLOSE 事件。 这是我的代码的简化版本: H
这article说如下: The Windows event mechanism (e.g. WaitForMultipleObjects()) can only wait on 64 event o
我正在重写我的软件中的代码以支持多个连接,直到现在,我都使用 select。为了让我的软件更便携,我改用了 WSAPoll。在WSAPoll中发现了一个Microsoft不会解决的错误后,我想更改为建
我对属于多线程套接字服务器的一段遗留 c++/winsock 代码有疑问。该应用程序创建一个线程来处理来自客户端的连接,通常一次有几百个连接。它通常可以毫无问题地运行数天(连续),然后突然停止接受连接
我用 WSAEventSelect 开发了一个回显服务器。它只允许 64 个连接。我该怎么办。 最佳答案 这听起来很像 MAXIMUM_WAIT_OBJECTS 限制,即 64。函数 WaitForM
我是一名优秀的程序员,十分优秀!