WSAEventSelect模型
程序员文章站
2022-04-24 14:33:37
...
4步走:
1.//1. 事件句柄和套接字句柄表
2.//2. 创建事件对象,并关联到新的套接字上
3.//3. 在所有事件上等待 //对每个事件调用WSAWaitForMultipleEvents函数,以便确定它的状态
4//获取来到的消息,WSAEnumNetworkEvents会自动重置受信事件
上代码:
#include "InitSock.h"
#include <stdio.h>
int main()
{
CInitSock initSock;
//1. 事件句柄和套接字句柄表
WSAEVENT eventArray[WSA_MAXIMUM_WAIT_EVENTS];
SOCKET socketArray[WSA_MAXIMUM_WAIT_EVENTS];
int nEventTotal = 0;
USHORT nPort = 9999;
SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == sListen)
{
return -1;
}
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(nPort);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
if (::bind(sListen, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
{
return -1;
}
::listen(sListen, 5);
//2. 创建事件对象,并关联到新的套接字上
WSAEVENT event = ::WSACreateEvent();
::WSAEventSelect(sListen, event, FD_ACCEPT|FD_CLOSE);
//添加到列表中
eventArray[nEventTotal] = event;
socketArray[nEventTotal] = sListen;
nEventTotal++;
//处理网络事件
while (TRUE)
{
//3. 在所有事件上等待
int nIndex = ::WSAWaitForMultipleEvents(nEventTotal, eventArray, FALSE, WSA_INFINITE, FALSE);
//对每个事件调用WSAWaitForMultipleEvents函数,以便确定它的状态
nIndex = nIndex - WSA_WAIT_EVENT_0;
for (int i=nIndex;i<nEventTotal;i++)
{
nIndex = ::WSAWaitForMultipleEvents(1, &eventArray[i], TRUE, 1000, FALSE);
if (nIndex == WSA_WAIT_FAILED || nIndex == WSA_WAIT_TIMEOUT)
{
continue;
}
else
{
//获取来到的消息,WSAEnumNetworkEvents会自动重置受信事件
WSANETWORKEVENTS event;
::WSAEnumNetworkEvents(socketArray[i], eventArray[i], &event);
if (event.lNetworkEvents & FD_ACCEPT) //接收到连接
{
MessageBox(NULL, "fd_accept", "",MB_OK);
if (event.iErrorCode[FD_ACCEPT_BIT] == 0) //没出错
{
if (nEventTotal > WSA_MAXIMUM_WAIT_EVENTS)
{
printf("too many connections...");
}
SOCKET sNew = ::accept(socketArray[i], NULL, NULL);
WSAEVENT event = WSACreateEvent();
::WSAEventSelect(sNew, event, FD_READ|FD_WRITE|FD_CLOSE);
//添加到列表
eventArray[nEventTotal] = event;
socketArray[nEventTotal] = sNew;
nEventTotal++;
}
}
else if (event.lNetworkEvents & FD_READ)
{
if (event.iErrorCode[FD_READ_BIT] == 0)
{
char szContent[512]={0};
int nRecv= ::recv(socketArray[i], szContent, 512, 0);
if (nRecv > 0)
{
szContent[nRecv] = '\0';
printf("收到数据 :%s", szContent);
}
}
}
else if (event.lNetworkEvents & FD_CLOSE)
{
if (event.iErrorCode[FD_CLOSE_BIT] == 0)
{
::closesocket(socketArray[i]);
for (int j=i;j<nEventTotal-1;j++)
{
socketArray[j] = socketArray[j+1];
eventArray[j] = eventArray[j+1];
}
nEventTotal--;
}
}
else if (event.lNetworkEvents & FD_WRITE)
{
char szContent[] = "server writed";
::send(socketArray[i], szContent, sizeof(szContent), 0);
}
}
}
}
return 0;
}
上一篇: FFmpeg 解码音视频实例及碰到的问题记录(二)
下一篇: python在终端里面显示一张图片