0
点赞
收藏
分享

微信扫一扫

io模型之异步事件模型

343d85639154 2022-04-06 阅读 155
tcp/ip

io模型 :

异步事件类型特点
 

简单的异步模型应用

 该模型接收 FD_XXX 之类的网络事件,通过事件对象句柄通知,单线程实现一对多通信

主要代码如下

//向windows注册,当有事件发生时会通知
    HANDLE h_event = WSACreateEvent();//默认人工   无信号
    //第一个参数是套接字,第二个是事件,第三个是网络信号类型
    if (!WSAEventSelect(m_sock, h_event, FD_ACCEPT))//成功返回0,否则返回SOCKET_ERROR
    {
        m_arrevent[currentnum] = h_event;//将套接字和信号量绑定在一起
        m_arraysock[currentnum] = m_sock;
        currentnum++;   
    }

 

        DWORD dwindex;
        WSANETWORKEVENTS we;
        //哪个信号量到了,就干什么事
        //等多个事件--有可能是fd_accept
        
        dwindex = WSAWaitForMultipleEvents(pthis->currentnum, pthis->m_arrevent, FALSE,          FALSE, 0);
        //                                 等待事件数量,     等待事件的集合   ,1是全都等到返回 ,等待时间 ,返回值         
        //                                                                       0是一个到就返回                
        dwindex -= WSA_WAIT_EVENT_0;//dwindex代表数组下标,返回最小索引值
        if (WSAEnumNetworkEvents(pthis->m_arraysock[dwindex],//事件的套接字
            pthis->m_arrevent[dwindex],//哪一个事件
            &we))//返回值一个  WSANETWORKEVENTS 类型指针
            continue;
        //信号为二进制数,不同位置的1代表不同的信号
        if (we.lNetworkEvents & FD_ACCEPT)//看是否触发FD_ACCEPT信号
        {
            //创建连接
            SOCKET sockwinter = accept(pthis->m_sock, 0, 0);
            if (sockwinter == INVALID_SOCKET)
                continue;
            HANDLE event = WSACreateEvent();
            if (!WSAEventSelect(sockwinter, event, FD_CLOSE | FD_READ))
            {
                pthis->m_arrevent[pthis->currentnum] = event;
                pthis->m_arraysock[pthis->currentnum] = sockwinter;
                pthis->currentnum++;
            }
        }
        if (we.lNetworkEvents & FD_READ)//是可读信号
        {
            char buf[1024] = { 0 };
            int nrecv = recv(pthis->m_arraysock[dwindex], buf, sizeof(buf), 0);
            if (nrecv >= 0)
                cout << buf << endl;
        }
        if (we.lNetworkEvents & FD_CLOSE)//断开连接信号
        {
            closesocket(pthis->m_arraysock[dwindex]);
            WSACloseEvent(pthis->m_arrevent[dwindex]);
            if (dwindex > 1)
            {//将最后一个位置的,转移到删除的位置
                pthis->m_arraysock[dwindex] = pthis->m_arraysock[pthis->currentnum - 1];
                pthis->m_arrevent[dwindex] = pthis->m_arrevent[pthis->currentnum - 1];
            }
            pthis->currentnum--;//最后一个位置空出来
        }
举报

相关推荐

0 条评论