天天看点

WinCE下 WSAWaitForMultipleEvents 事件模型实现并发IO

直接贴代码

void CListenAction::Init()

{

    // 初始化套接字库

    if (!InitSocketLib())

    {

       TRACE(_T("初始化套接字库失败"));

        return ;

    }

    // 创建服务器端监听套接字

    SOCKET listenSocket;

    listenSocket = socket(AF_INET, SOCK_STREAM, 0);

    if (INVALID_SOCKET == listenSocket)

    {

        TRACE(_T("socket error: %d\n"),WSAGetLastError());

        return;

    }

    // 本地地址

    SOCKADDR_IN localAddr;

    localAddr.sin_family = AF_INET;

    // 获取本机IP地址

    char szIPBuf[100];

    memset(szIPBuf, 0, 100);

    CCommUtility::GetLocalIP(szIPBuf, sizeof(szIPBuf));

    localAddr.sin_addr.S_un.S_addr = inet_addr(szIPBuf);

    // 设置端口号

    localAddr.sin_port = htons(SERVER_PORT);

    INT iRetTmp = bind(listenSocket, (SOCKADDR *)&localAddr, sizeof(localAddr));

    if (SOCKET_ERROR == iRetTmp)

    {

        TRACE(_T("bind error: %d\n"),WSAGetLastError());

        return;

    }

    iRetTmp = listen(listenSocket, LISTEN_QUEUE_LENGTH);

    if (SOCKET_ERROR == iRetTmp)

    {

        TRACE(_T("listen error: %d\n"),WSAGetLastError());

        return;

    }

    // 添加监听主套接字到通信对象数组

    SOCKET_OBJ socketObj;

    socketObj.sd = listenSocket;

    socketObj.emConnectType = LISTEN;

    socketObj.emSocketType = TCP_SOCKET;

    m_arraySocket.Add(socketObj);

    // 添加监听事件到事件数组 关联事件

    WSAEVENT listenEvent = WSACreateEvent();

    int iRet = WSAEventSelect(listenSocket, listenEvent, FD_ACCEPT | FD_CLOSE);

    if (iRet != 0)

   {

       TRACE(_T("WSAEventSelect failed: %d\n"),WSAGetLastError());

       return;

   }

    m_arrayEvent.Add(listenEvent);

    // 开始监听事件

    StartListenEvent();

}

/// @brief  开始监听套接字事件

VOID CListenAction::StartListenEvent()

{

    // 网络事件

    WSANETWORKEVENTS netEvents;

    // 返回索引

    DWORD dwIndex = 0;

    DWORD dwRetTemp;

    // 循环等待网络事件

    while (TRUE)

    {

        // 判断线程是否退出

        dwRetTemp = WaitForSingleObject(m_ExitEvent.m_hObject, 0);

        if (WAIT_OBJECT_0 == dwRetTemp)

        {

            // 退出

            break;

        }

        // 第一个有事件的通信对象索引

        dwIndex = WSAWaitForMultipleEvents(m_arrayEvent.GetCount(),

                                           &m_arrayEvent[0],

                                           FALSE,

                                           NETWORK_EVENT_WAIT_TIME,

                                           FALSE);

        // 失败

        if (WSA_WAIT_FAILED == dwIndex)

        {

            TRACE(_T("WSAWaitForMultipleEvents error: %d\n"),WSAGetLastError());

            return;

        }

        else

        {

            if (WSA_WAIT_TIMEOUT != dwIndex)

            {

                dwIndex -= WSA_WAIT_EVENT_0;

                for (INT i = dwIndex; i < m_arrayEvent.GetCount(); i++)

                {

                    dwIndex = WSAWaitForMultipleEvents(1, &m_arrayEvent[i], FALSE, 0, FALSE);

                    if ((WSA_WAIT_FAILED != dwIndex) && (WSA_WAIT_TIMEOUT != dwIndex))

                    {

                        WSAEnumNetworkEvents(m_arraySocket[i].sd, m_arrayEvent[i], &netEvents);

                        if (netEvents.lNetworkEvents & FD_ACCEPT)

                        {

                            if (netEvents.iErrorCode[FD_ACCEPT_BIT] != 0)

                            {

                                TRACE(_T("FD_ACCEPT error: %d\n"),netEvents.iErrorCode[FD_ACCEPT_BIT]);

                                break;

                            }

                            // 接收请求连接的客户端

                            AcceptClientConnection(m_arraySocket[i].sd);

                        }

                        if (netEvents.lNetworkEvents & FD_READ)

                        {

                            if (netEvents.iErrorCode[FD_READ_BIT] != 0)

                            {

                                // 记录日志

                                TRACE(_T("FD_READ error: %d\n"),netEvents.iErrorCode[FD_READ_BIT]);

                                break;

                            }

                            // 报告数据到达事件

                            ReportDataArrive(i);

                        }

                        if (netEvents.lNetworkEvents & FD_CLOSE)

                        {

                            if (netEvents.iErrorCode[FD_READ_BIT] != 0)

                            {

                                // 记录日志

                                TRACE(_T("FD_CLOSE error: %d\n"),netEvents.iErrorCode[FD_CLOSE_BIT]);

                                break;

                            }

                            // 断开连接

                            DisConnect(m_arraySocket[i].sd);

                        }

                    }

     else

     {

      TRACE(_T("WSAWaitForMultipleEvents error: %d\n"),WSAGetLastError());

     }

                }

            }

   else

   {

    TRACE(_T("time out\n"));

   }

        }

    }

}

继续阅读