io模型之异步事件模型

一.io模型 :

异步选择模型 :像操作系统注册信息(socket,网络事件,消息),当指定网络事件发生时,接收消息
异步事件模型 :向操作系统注册信息(socket,网络事件,事件),当指定网络事件发生时,将事件置为有信号(最快)

二.异步事件类型的特点
 

1.被动通知
2.个数限制 64 (多线程 多个数组)
3.性能较优

存在问题

1.还是会阻塞:因为他需要自己从内存中拷贝信息

2.如果同时有两个事件发生信号,只会返回索引最小的那个,可能会造成数据丢失

三.流程简要

将创建好的套接字向windows注册,当相应套接字事件发生时,会返回网络信号,还有套接字在集合中的位置,根据相应位置的套接字和网络信号类型去处理。

四.简单的异步模型应用

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

网络事件是01串,可以通过相异注册多个网络事件

主要代码如下

//向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;//dwindex代表数组下标
WSANETWORKEVENTS we;
//哪个信号量到了,就干什么事
//等多个事件--有可能是fd_accept

dwindex = WSAWaitForMultipleEvents(pthis->currentnum,// 等待事件数量
                                   pthis->m_arrevent,//等待事件的集合
                                               FALSE, //1是全都等到返回,0是一个到就返回
                                               FALSE, //等待时间
                                                  0);//返回值

dwindex -= WSA_WAIT_EVENT_0;//dwindew,返回最小索引值,减去WSA_WAIT_EVENT_0为下标

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;

    //把创建的winter套接字向windows注册,信号为读取或者关闭
    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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值