您当前的位置: 首页 >  网络
  • 1浏览

    0关注

    322博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

boost库中优秀的网络库asio

森明帮大于黑虎帮 发布时间:2022-08-29 16:18:16 ,浏览量:1

文章目录
  • 一、须知
  • 二、ASIO
  • 三、我们将从研究同步操作开始
  • 四、当使用异步操作时,会发生不同的事件序列
  • 五、Proactor模型
  • 六、常用内容
  • 七、C++ 建立本地网络服务器 (Boost.Asio库)
      • 1.服务器用例
        • 1.建造(Build)
        • 2.聆听(Listen)
        • 3.处理(Operation)
        • 4.异步(Async)
  • 八、简易并发服务器类
  • 总诉

一、须知

开发大型项目,肯定需要使用一些框架,这些框架可以由你自己亲自手工实现,也可以直接引用第三方库。

1、自己实现框架 优点:程序的所有细节都能非常清楚的掌握。 缺点:工作量大、难度高。

2、引用第三方库 优点:选择一个稳定、靠谱的第三方框架,将很大程度降低工作量、提高开发效率,将精力重点放在业务逻辑。 缺点:库本身有功能和性能问题。

因此,请尽量使用优秀的第三方库,避免重复造轮子(自己造的轮子问题频发)。

二、ASIO

asio 是boost库中优秀的网络库。asio是一个异步的io库,支持以同步或异步的方式处理事件,也可以用于基于tcp或udp的网络通信。

(1)可移植到windows、linux、FreeBSD。 (2)可扩展性。 (3)效率很高。 (4)易使用,类 Socket API 编程模型。

支持同步、异步通信方式。

三、我们将从研究同步操作开始

asio可以进行io对象(比如socket套接字)进行同步操作和异步操作。 在使用Asio之前,对Asio的各个部分、你的程序以及它们是如何一起工作的有个概念的了解是很有用的。作为一个介绍性的例子,让我们考虑一下在套接字上执行连接操作时会发生什么。 在这里插入图片描述 你的程序至少会有一个I/O执行上下文,比如asio::io_context对象,asio::thread_pool对象,或者asio::system_context。这个I/O执行上下文表示程序到操作系统I/O服务的链接。

asio::io_context io_context;

要执行I/O操作,你的程序需要一个I/O对象,比如一个TCP套接字:

asio::ip::tcp::socket socket(io_context);

当执行同步连接操作时,会发生以下事件序列:

  1. 你的程序通过调用I/O对象来启动连接操作
socket.connect(server_endpoint);
  1. I/O对象将请求转发给I/O执行上下文。

  2. I/O执行上下文调用操作系统来执行连接操作。

  3. 操作系统将操作的结果返回给I/O执行上下文。

  4. I/O执行上下文将操作产生的任何错误转换为asio::error_code类型的对象。error_code可以与特定的值进行比较,或者作为布尔值进行比较(如果结果为假,则表示没有发生错误)。然后将结果转发回I/O对象。

  5. 如果操作失败,I/O对象会抛出一个asio::system_error类型的异常。如果初始化操作的代码被写成:

asio::error_code ec;
socket.connect(server_endpoint, ec);

然后error_code变量ec将被设置为操作的结果,并且不会抛出异常。

四、当使用异步操作时,会发生不同的事件序列

在这里插入图片描述

  1. 你的程序通过调用I/O对象来初始化连接操作
socket.async_connect(server_endpoint, your_completion_handler);

其中your_completion_handler是一个带有签名的函数或函数对象:

void your_completion_handler(const asio::error_code& ec);

所需的确切签名取决于正在执行的异步操作。参考文档指出了每个操作的适当形式。

  1. I/O对象将请求转发给I/O执行上下文。

  2. I/O执行上下文向操作系统发出信号,说明它应该启动异步连接。 在这里插入图片描述

  3. 操作系统通过将结果放置在一个队列中表示连接操作已经完成,准备由I/O执行上下文获取。

  4. 当使用io_context作为I/O执行上下文时,你的程序必须调用io_context::run()(或类似的io_context成员函数)以便检索结果。当有未完成的异步操作时,调用io_context::run()会阻塞,所以你通常会在你开始第一个异步操作时调用它。

  5. 在调用io_context::run()时,I/O执行上下文会将操作的结果从队列中取出,转换成一个error_code,然后将其传递给完成处理程序。

五、Proactor模型

在这里插入图片描述

  • 各部分内容
  1. — Asynchronous Operation (异步操作)
  • 定义一个异步执行的操作,如Socket异步读写。
  1. Asynchronous Operation Processor (异步操作执行器)
  • 执行一个异步操作,并执行完成事件队列中的队列事件,从更高层次上说,像reactive_socket_service的服务就是一个异步操作处理器。
  1. Completion Event Queue (事件完成队列)
  • 缓存完成事件直到被异步事件分离器弹出队列。
  1. Completion Handler (处理器)
  • 处理异步操作的结果,处理器是函数对象,往往使用bind创建。
  1. Asynchronous Event Demultiplexer (异步事件分离器)
  • 阻塞等待在完成事件队列中事件发生,之后向调用者返回完成事件。
  1. Proactor
  • 调用异步事件信号分离器将事件移出队列,并分配一个关联的处理器(如调用函数对象),这个功能封装在io_service类中。
  1. Initiator
  • 执行特定程序代码启动异步操作,初始化器通过如basic_stream_socket等高层次接口与异步操作处理器交互,并返回reactive_socket_service等类型的服务代理。
六、常用内容
  1. asio::io_context
  • asio提供的一个基本的io对象,只有调用其run方法的线程才会被asio调度去执行任务,可以通过post方法添加一个任务。
 asio::io_context main;
    //make_work_guard作用,创建一个executor_work_guard对象,在构造时通知io_context有任务开始,保证run方法不会退出
    //析构时相反,让run方法在没有未完成任务时退出
    auto i = aso::make_work_guard(main);
    another.post([&main]()
    {
        std::cout             
关注
打赏
1664288938
查看更多评论
0.0954s