• Windows网络模型之异步选择模型(基于消息机制)


    异步选择模型(基于消息机制–核心是消息队列


    什么是消息机制?

    答:

    • Windows处理用户行为的方式之一
    • 消息机制的核心是消息队列,所有用户的操作都可以被认为是一个消息,当某些用户动作发生后,其对应的消息就会进入操作系统维护的消息队列;
    • 程序员负责将消息队列中的消息取出,并根据消息类型进行分类处理;消息队列是由操作系统维护的;
    • 因此消息机制是有序地处理消息队列中的所有消息,早产生的消息早处理!

    Windows下的异步选择模型最具有代表性的函数是WSAAsyncSelect()函数,是基于消息机制条件下的select()函数的升级版

    异步选择模型的逻辑

    1. 异步选择模型其实是Windows独有的,Win操作系统为每一个窗口维护一个消息队列,这是实现消息机制核心中的核心。不过简单的是,程序员并不需要去创建消息队列,消息队列的创建将新消息装进消息队列都由操作系统完成

    2. 首先应该有一个窗口,因为有了窗口才有消息队列

      // 1.创建窗口结构体
      WNDCLASSEX
      // 2.注册窗口结构体
      RegisterClassEx
      // 3.创建窗口
      CreateWindowEx
      // 4.显示窗口
      ShowWindow
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    3. 之后就是利用循环,不断地获取消息翻译消息分发消息

      // 1.获取消息,每次取出消息队列中的头一个消息
      GetMessage()  
      // 2.翻译消息
      TranslateMessage()
      // 3.分发消息
      DispatchMessage()
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    4. 因为要处理网络连接与通信问题,所以需要创建自定义消息,并将自定义消息套接字socket以及我们关心的动作绑定在一起然后投递给操作系统。此时使用的关键函数就是异步选择模型的灵魂所在:WSAAsyncSelect()

      预定义的消息都是如鼠标按下键盘按下窗口退出等…

      而类似于网络连接收发消息是需要程序员自定义的

      int WSAAsyncSelect(
        SOCKET s,			// 我们关心的socket,如用于接收连接的服务器socket、与客户端通信的socket
        HWND   hWnd,		// 将该消息投递给哪个窗口,也即希望该消息进入哪个窗口的消息队列
        u_int  wMsg,		// 消息号
        long   lEvent		// 某个动作(网络事件)如:FD_ACCEPT   FD_READ   FD_WRITE  FD_CLOSE等
      );
      
      // 如何自定义消息呢?
      #define UM_MYMSG WM_USER + 1  // UM_MYMSG是我自定义的名字  WM_USER之后的消息ID是可以自由指定的
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    5. 还有一个隐含的内容:分发消息之后,程序如何执行呢?其实程序会调用消息响应函数(也可以称为消息回调函数),用来响应不同的消息,如果我们有自定义消息,就需要在该函数中编写相应的分类处理代码。该函数的声明如下:

      // 注意GetMessage()每次只会取出一个消息,因此下面的回调函数,每次调用也只是响应一个消息
      // 下面的函数,其函数名可变,只要在创建窗口的时候,指定窗口的消息处理回调函数为这个函数名就行
      LRESULT CALLBACK WinBackProc(
          HWND hWnd,			// 表示该函数负责处理哪个窗口的消息
          UINT msgID,			// 指定了消息ID,因此在函数内部就可通过这个ID当前要处理的消息是什么
          WPARAM wparam,		// 指定了是哪个socket的消息
          LPARAM lparam		// 指定了具体的事件(行为) 如:FD_ACCEPT   FD_READ   FD_WRITE  FD_CLOSE等
      )
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

      因此我们要在该函数中,编写关于socket接收连接收发消息的代码,也就是所谓的分类处理


    如何回答对异步选择模型的理解?

    首先异步选择模型基于消息机制,消息机制的核心是消息队列,通常消息队列伴随着windows窗口一起出现,由win操作系统创建和添加新消息进队列

    异步选择模型其实也是基本的select模型的升级版,他和事件选择模型一样,都是解决了select模型中select()函数执行阻塞的问题,不同在于后者是基于事件机制。

    他的核心逻辑就是,将socket自定义消息具体事件(如FD_ACCEPT FD_READ FD_WRITE FD_CLOSE)绑定在一起,然后投递给操作系统去监管,如果相应的消息产生就会被操作系统装进消息队列

    我们只需要从消息队列中依次取出每一个消息在窗口的消息响应函数中获得消息ID、对应的Socket、以及具体事件,然后分类处理即可


    推荐阅读:(三)Windows网络模型之重叠IO模型(事件通知和完成例程)

  • 相关阅读:
    Go fsnotify简介
    【SQL刷题】Day12----SQL汇总数据专项练习
    易点易动固定资产管理系统:实现财务与OA系统的无缝对接,高效管理固定资产
    贪心算法-金条切割问题
    Uniapp零基础开发学习笔记(4) -顶部导航栏titleNView的制作
    require模块化语法
    study_linux02
    Flutter教程之Dart 和 Flutter 的工厂设计模式
    小程序添加分享和禁用分享功能
    【C++ Efficiency】找到可能产生“临时对象”的地方
  • 原文地址:https://blog.csdn.net/qq_40459977/article/details/126210175