WSAEventSelect模型下何时触发FD_CLOSE
请教各位高手指教。
直接上代码:
#include <iostream>
#include "InitSocket.h"
#pragma comment (lib,"ws2_32.lib")
//初始化网络环境
CInitSocket gcInitSocket;
void main()
{
SOCKET sServer = socket(AF_INET,SOCK_STREAM,0);
if (INVALID_SOCKET == sServer)
{
printf("创建服务器套接字失败,错误编号:%d\n",WSAGetLastError());
exit(0);
}
sockaddr_in addrBind;
addrBind.sin_family = AF_INET;
addrBind.sin_addr.S_un.S_addr = htonl(ADDR_ANY);
addrBind.sin_port = htons(8080);
int iBind = bind(sServer,(sockaddr*)&addrBind,sizeof(sockaddr));
if (SOCKET_ERROR == iBind)
{
printf("bind failed\n");
exit(0);
}
int iListen = listen(sServer,SOMAXCONN);
if (SOCKET_ERROR == iListen)
{
printf("listen failed\n");
exit(0);
}
WSAEVENT eventArr[WSA_MAXIMUM_WAIT_EVENTS];
SOCKET socketArr[WSA_MAXIMUM_WAIT_EVENTS];
int iArrSize = 0;
WSAEVENT eventForSRV = WSACreateEvent();
eventArr[iArrSize] = eventForSRV;
socketArr[iArrSize] = sServer;
++iArrSize;
if (WSA_INVALID_EVENT == eventForSRV)
{
printf("create wsaevent failed\n");
exit(0);
}
WSAEventSelect(sServer,eventForSRV,FD_ACCEPT | FD_CLOSE);
while (1)
{
int iIndex = WSAWaitForMultipleEvents(iArrSize,eventArr,false,INFINITE,false);
if (WSA_WAIT_FAILED == iIndex || WSA_WAIT_TIMEOUT == iIndex)
{
continue;
}
iIndex -= WSA_WAIT_EVENT_0;
for (int i = iIndex;i!=iArrSize;++i)
{
iIndex = WSAWaitForMultipleEvents(1,&eventArr[i],true,1000,false);
if (WSA_WAIT_FAILED == iIndex || WSA_WAIT_TIMEOUT == iIndex)
{
continue;
}
else
{
WSANETWORKEVENTS eventTmp;
WSAEnumNetworkEvents(socketArr[i],eventArr[i],&eventTmp);
if (eventTmp.lNetworkEvents & FD_ACCEPT)
{
if (eventTmp.iErrorCode[FD_ACCEPT_BIT] != 0)
{
continue;
}
sockaddr_in addrAccept;
int iLength = sizeof(sockaddr);
SOCKET sAccept = accept(socketArr[i],(sockaddr*)&addrAccept,&iLength);
WSAEVENT eventAccept = WSACreateEvent();
printf("IP:%s,端口:%d\n",inet_ntoa(addrAccept.sin_addr),ntohs(addrAccept.sin_port));
WSAEventSelect(sAccept,eventAccept,FD_READ || FD_WRITE || FD_CLOSE);
socketArr[iArrSize] = sAccept;
eventArr[iArrSize] = eventAccept;
++iArrSize;
}
else if (eventTmp.lNetworkEvents & FD_READ)
{
if (0 != eventTmp.iErrorCode[FD_READ_BIT])
{
continue;
}
char chRecv[200] = {0};
int iRecv = recv(socketArr[i],chRecv,200,0);
if (SOCKET_ERROR == iRecv)
{
printf("recv failed\n");
continue;
}
printf("%s\n",chRecv);
}
else if (eventTmp.lNetworkEvents & FD_CLOSE)
{
// if (0 != eventTmp.iErrorCode[FD_CLOSE_BIT])
// {
// continue;
// }
closesocket(socketArr[i]);
for (int i2 = i;i2!=iArrSize - 1;++i2)
{
socketArr[i] = socketArr[i + 1];
eventArr[i] = eventArr[i + 1];
}
--iArrSize;
printf("one client closed\n");
}
}
}
}
}相关推荐
WSAEventSelect模型
- **错误处理**:如果套接字出现错误,如断开连接,FD_CLOSE事件会被触发,服务器需要关闭套接字并清理资源。### 4.
Windows Sockets网络编程(3)WSAEventSelect模型开发
WSAEventSelect模型是非阻塞的,该模型允许在一个或者多个套接字上接收以事件为基础的网络事件通知。Windows Sockets应用程序在创建套接字后,调用WSAEventSelect()函数,将一个事件对象与网络事件集合关联在一起。当网络事件发生时,应用程序以事件的形式接收网络事件通知。 创建TCP 这里不再赘述了,能来到本文的,相信基本功已经不用多讲了。实在不明白的可以阅读《Windows Sockets网络编程(0)TCP In Action》一文,该文详细的叙述了TCP创建的整个过
采用C++语言实现的WSAEventSelect I/O模型
| FD_CLOSE);if (ret == SOCKET_ERROR) { // 错误处理}```接下来,你需要在一个循环中调用WaitForSingleObject或WaitForMultipleObjects
WSAEventSelect事件选择网络模型
- **FD_ACCEPT**:服务器套接字准备好接受新的连接请求。- **FD_CONNECT**:连接操作完成。- **FD_CLOSE**:套接字关闭。**3.
VC网络编程模型示例 - WSAEventSelect
这些网络事件包括:- FD_READ:数据可读- FD_WRITE:数据可写- FD_OOB:收到紧急数据- FD_ACCEPT:新连接请求到达- FD_CLOSE:连接被关闭当这些事件发生时,系统会设置预先指定的事件对象


