bimuyu 发表于 2017-6-2 11:07:40

WSAEventSelect模型

4步走:
1.//1. 事件句柄和套接字句柄表
2.//2. 创建事件对象,并关联到新的套接字上
3.//3. 在所有事件上等待 //对每个事件调用WSAWaitForMultipleEvents函数,以便确定它的状态
4//获取来到的消息,WSAEnumNetworkEvents会自动重置受信事件
上代码:
#include "InitSock.h"
#include <stdio.h>
int main()
{
        CInitSock initSock;
        //1. 事件句柄和套接字句柄表
        WSAEVENT eventArray;
        SOCKET socketArray;
        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*)&amp;sin, sizeof(sin)) == SOCKET_ERROR)
        {
                return -1;
        }
        ::listen(sListen, 5);

        //2. 创建事件对象,并关联到新的套接字上
        WSAEVENT event = ::WSACreateEvent();
        ::WSAEventSelect(sListen, event, FD_ACCEPT|FD_CLOSE);

        //添加到列表中
        eventArray = event;
        socketArray = 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, &amp;eventArray, TRUE, 1000, FALSE);
                        if (nIndex == WSA_WAIT_FAILED || nIndex == WSA_WAIT_TIMEOUT)
                        {
                                continue;
                        }
                        else
                        {
                                //获取来到的消息,WSAEnumNetworkEvents会自动重置受信事件
                                WSANETWORKEVENTS event;
                                ::WSAEnumNetworkEvents(socketArray, eventArray, &amp;event);
                                if (event.lNetworkEvents &amp; FD_ACCEPT) //接收到连接
                                {
                                        MessageBox(NULL, "fd_accept", "",MB_OK);
                                        if (event.iErrorCode == 0) //没出错
                                        {
                                                if (nEventTotal > WSA_MAXIMUM_WAIT_EVENTS)
                                                {
                                                        printf("too many connections...");
                                                }
                                                SOCKET sNew = ::accept(socketArray, NULL, NULL);
                                                WSAEVENT event = WSACreateEvent();
                                                ::WSAEventSelect(sNew, event, FD_READ|FD_WRITE|FD_CLOSE);

                                                //添加到列表
                                                eventArray = event;
                                                socketArray = sNew;
                                                nEventTotal++;
                                        }
                                }
                                else if (event.lNetworkEvents &amp; FD_READ)
                                {
                                        if (event.iErrorCode == 0)
                                        {
                                                char szContent={0};
                                                int nRecv= ::recv(socketArray, szContent, 512, 0);
                                                if (nRecv > 0)
                                                {
                                                        szContent = '\0';
                                                        printf("收到数据 :%s", szContent);
                                                }
                                        }
                                }
                                else if (event.lNetworkEvents &amp; FD_CLOSE)
                                {
                                        if (event.iErrorCode == 0)
                                        {
                                                ::closesocket(socketArray);
                                                for (int j=i;j<nEventTotal-1;j++)
                                                {
                                                        socketArray = socketArray;
                                                        eventArray = eventArray;
                                                }
                                                nEventTotal--;
                                        }
                                }
                                else if (event.lNetworkEvents &amp; FD_WRITE)
                                {
                                        char szContent[] = "server writed";
                                        ::send(socketArray, szContent, sizeof(szContent), 0);
                                }
                        }
                }
        }
        return 0;
}
页: [1]
查看完整版本: WSAEventSelect模型