TCP/IP网络编程学习笔记(十一)

  1. Windows下类似与Linux下的epoll异步通知IO模型(不是异步IO模型)是基于WSAEventSelect实现的(还有一种WSAAsyncSelect也能实现,不过一般用于UI);

  2. WSAEventSelect实现的异步通知IO模型的过程:

    • 使用WSACreateEvent()创建一个手动重置事件(注意结束时要用WSACloseEvent()来销毁这个手动重置事件);
    • 使用WSAEventSelect()将一个句柄(比如socket句柄)与上一步创建的手动重置事件进行绑定,调用此函数时第三个参数传入事件类型,表示当对应的句柄发生此类型的事件的时候,就将手动重置事件变成signaled状态(激发态)。注意,这个函数每次调用只能将一个句柄与一个手动重置事件进行绑定,类似与epoll中的epoll_ctl()每次只能注册一个;
    • 调用WSAWaitForMultipleEvents()来等待一组事件的发生。一组事件是通过数组传入的,可以选择等待任意一个事件发生就返回,也可以选择等待所有事件都发生了才返回,因此,这是一个阻塞函数,类似与epoll中的epoll_wait()。不过,注意,等待的最大事件个数一般为64个,可以通过宏WSA_MAXIMUM_WAIT_EVENTS来获取最大可等待事件个数;
    • 上一步只能得到所有被激发事件中的第一个被激发事件的数组下标(通过返回值获得),如果想得到所有被激发的事件,则要循环调用WSAWaitForMultipleEvents(),比如:
      int posInfo = WSAWaitForMultipleEvents(numOfSock, hEventArray, FALSE, WSA_INFINITE, FALSE);
      int startIdx = posInfo - WSA_WAIT_EVENT_0;
      .....
      for (int i = startIdx; i < numOfSock; ++i)
      {
         int sigEventIdx = WSAWaitForMultipleEvents(1, &hEventArray[i], TRUE, 0, FALSE);
         ......
      }
      
      注意,后面循环里面不再是无限等待,而是不等待,只是为了拿到已经激发的事件的下标;
    • 通过函数WSAEnumNetWorkEvents()来区分事件的类型。此函数需要传入一个socket句柄,以及之前通过WSAEventSelect()进行绑定的手动重置事件的句柄,并传入一个WSANETWORKEVENTS结构体指针,用来返回事件的类型以及出错类型;
    • 通过检测事件类型来得到当前socket句柄发生了什么事件,从而决定做什么事情。
  3. 注意,如果要删除事件数组中的一个事件,必须将数组压缩,中间不能空,要将后面的事件前移一个位置;

  4. 事件的类型有如下几种:

    FD_READ:是否存在需要接收的数据;
    FD_WRITE:能否以非阻塞方式传输数据(意思应该是输出缓冲区是否可以填充数据,而不需要等待);
    FD_OOB:是否收到带外数据;
    FD_ACCEPT:是否有新的连接请求;
    FD_CLOSE:是否有断开连接的请求(应该是对法发送了EOF)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值