首页 > 其他分享 >Boost.Asio网络库 学习笔记

Boost.Asio网络库 学习笔记

时间:2023-09-09 12:44:46浏览次数:44  
标签:Asio asio io Boost 笔记 context boost

Asio网络库 学习笔记


Boost官网:https://www.boost.org/

Boost库 许可证:

//          Copyright Joe Coder 2004 - 2006.
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          https://www.boost.org/LICENSE_1_0.txt)

1. Asio简介

Asio是一个跨平台的C++网络库,它是Boost库的一部分,它是异步输入输出的核心。Asio提供了一组异步的I/O操作,包括TCP和UDP的socket、定时器、串口等。Asio的核心是一个事件循环,它使用epoll、kqueue、IOCP等系统调用来实现异步I/O操作。Asio的事件循环是单线程的,但是它提供了一些接口来实现多线程的异步操作。

这里引用文章Boost asio 官方教程简介的例子:异步任务的典型例子是网络应用。 如果数据被发送出去了,比如发送至 Internet,通常需要知道数据是否发送成功。 如果没有一个象 Boost.Asio 这样的库,就必须对函数的返回值进行求值。 但是,这样就要求待至所有数据发送完毕,并得到一个确认或是错误代码。 而使用 Boost.Asio,这个过程被分为两个单独的步骤:第一步是作为一个异步任务开始数据传输。 一旦传输完成,不论成功或是错误,应用程序都会在第二步中得到关于相应的结果通知。 主要的区别在于,应用程序无需阻塞至传输完成,而可以在这段时间里执行其它操作。

2. Asio的使用

2.1. Asio的安装

这里举例Unix/Linux 环境下的安装。

Asio是Boost库的一部分,所以要使用Asio,首先要安装Boost库。

  1. 下载Boost库

    Boost库的下载地址:https://boostorg.jfrog.io/artifactory/main/release/
    或者 https://sourceforge.net/projects/boost/files/

    首先我们创建一个目录,用来存放Boost库的源码和编译后的库文件。

    # 进入用户目录
    cd ~ 
    # 创建Boost目录
    mkdir Boost  
    # 进入Boost目录
    cd Boost  
    

    然后下载Boost库的源码,这里下载的是Boost 1.83.0版本的源码。

    wget https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/boost_1_83_0.tar.gz
    

    国内下载可能有点慢。建议用第二个网站。

  2. 解压Boost库

    tar -zxvf boost_1_83_0.tar.gz
    
  3. 编译Boost库

    cd boost_1_83_0
    ./bootstrap.sh
    ./b2
    

    编译完成后,会有如下提示:

    The Boost C++ Libraries were successfully built!
    
    The following directory should be added to compiler include paths:
    
        /home/username/boost/boost_1_83_0
    
    The following directory should be added to linker library paths:
    
        /home/username/boost/boost_1_83_0/stage/lib
    

    这里的username是你的用户名。

  4. 安装Boost库

    sudo ./b2 install
    

注意,由于Asio库使用了C++11的特性,所以编译时最好要加上-std=c++11选项,并且Asio使用了thread进行异步操作,所以编译时加上-pthread选项。

3. Asio工作原理

这里主要参考Asio官方文档

对于asio库,程序至少要包含一个io_context对象,这个对象代表程序链接到操作系统的I/O服务。io_context对象提供了一种将事件处理程序与操作系统的I/O服务进行交互的方法。boost::asio::io_contextboost::asio::thread_poolboost::asio::system_context

boost::asio::io_context io_context;

执行I/O操作都需要一个I/O对象,比如socket、定时器、串口等。

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

有两种类型的I/O操作:同步操作和异步操作。同步操作会阻塞当前线程,直到操作完成。异步操作会在操作完成后调用一个事件处理程序。

对于同步操作:

  1. 程序在开始阶段需要连接I/O对象。

    socket.connect(server_endpoint);
    
  2. I/O对象将请求转发到io_context对象。

  3. io_context对象调用操作系统来执行连接操作。

  4. 操作系统将操作结果返回到io_context对象。

  5. io_context对象将操作产生的任何错误转换为类型的对象。可以将与特定值进行比较,也可以作为布尔值进行测试(其中结果表示没有发生错误)。然后将结果转发回I/O对象。boost::system::error_codeerror_codefalse

  6. 如果操作失败,I/O对象将引发一个类型的异常。如果启动操作的代码改为:boost::system::system_error

    boost::system::error_code ec;
    socket.connect(server_endpoint, ec);
    

然后将变量设置为操作的结果,并且不会引发异常。error_codeec

对于异步操作:

  1. 您的程序通过调用I/O对象来启动连接操作:

    socket.async_connect(server_endpoint, your_completion_handler);
    

    其中是具有签名的函数或函数对象:your_completion_handler

    void your_completion_handler(const boost::system::error_code& ec);
    

    所需的确切签名取决于正在执行的异步操作。

  2. I/O对象将请求转发到io_context对象。

  3. io_context对象向操作系统发出信号,表示它应该启动异步连接。

    等待(在同步情况下,此等待将完全包含在连接操作的持续时间内。)
    (官方文档里给的词是 Time passes. 个人认为其含义是io_context对象等待系统响应。按我个人的理解:此时系统并不会立即响应请求,而是将请求放入队列,按照系统调度响应。此时io_context对象可以进行其他操作,也可以进行等待。)

  1. 操作系统通过将结果放在队列中来指示连接操作已经完成,该队列准备由io_context对象拾取。
  2. 当使用作io_context对象时,程序必须调用(或调用类似的成员函数之一)才能检索结果。在有未完成的异步操作时对块的调用,因此通常在启动第一个异步操作后立即调用它。io_contextio_context::run()io_contextio_context::run()
  3. 在对的调用中,I/O执行上下文将操作的结果排成队列,将其转换为,然后将其传递给您的完成处理程序。io_context::run()error_code

4. Asio的使用

4.1 简单使用

下面这个程序用来实现一个简单的UDP广播。

#include <iostream>
#include <boost/asio.hpp>

int main() {
    try {
        boost::asio::io_service io_service; // 创建io_service对象
        boost::asio::ip::udp::socket socket(io_service); // 创建socket对象

        // 设置广播地址和端口
        boost::asio::ip::udp::endpoint broadcast_endpoint(
            boost::asio::ip::address::from_string("255.255.255.255"), 50001);

        // 开启广播选项
        socket.open(boost::asio::ip::udp::v4()); // 打开套接字
        socket.set_option(boost::asio::socket_base::broadcast(true)); // 设置广播选项

        // 绑定套接字到本地端口
        boost::asio::ip::udp::endpoint local_endpoint(
            boost::asio::ip::address::from_string("0.0.0.0"), 0);
        socket.bind(local_endpoint); // 绑定套接字到本地端口

        std::string message = "Hello, UDP Broadcast!";
        socket.send_to(boost::asio::buffer(message), broadcast_endpoint);   // 发送广播消息

        std::cout << "Sent message: " << message << std::endl;
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }

    return 0;
}

标签:Asio,asio,io,Boost,笔记,context,boost
From: https://www.cnblogs.com/BryceAi/p/17689249.html

相关文章

  • Python学习笔记:pandas.Series.str.split分列
    split()方法通过指定分隔符对字符串进行切分,返回分割后的字符串列表  pandas.str.split分列Series.str.split(pat=None,expand=False)  返回分割后的Series ......
  • 【笔记】在线凸优化 - Ch1. Introduction
    1.1TheOnlineConvexOptimizationSetting在线凸优化Onlineconvexoptimization(OCO),是一个带有博弈论、统计学习、凸优化的新玩意给出如下问题叙述:考虑一种博弈游戏,回合制,第\(t\in[T]\)回合,先由玩家从决策集\({\calK}\in\mathbb{R}^n\)中选择一个决策\({\bfx}......
  • 【笔记】机器学习基础 - Ch6. Kernel Methods
    6.1Introduction继续从二分类模型出发,实际情况中样本通常不是线性可分的一种思路是增大特征空间的维度,也就是加入原本特征的组合,即一个从\(\calX\)到更高维\(\mathbb{H}\)的非线性映射\(\Phi:\calX\to\mathbb{H}\),从而在\(\mathbb{H}\)可能变得线性可分;尽管SVM对有......
  • solidworks 2023 SP3.0 安装笔记
    参考文献:Crack自带readme.txthttps://mp.weixin.qq.com/s?__biz=Mzk0NjI3ODE4OQ==&mid=2247592805&idx=1&sn=a8af2a6130ebb82972d2e09df555a90b&chksm=c30bb127f47c3831e9a82129098132c06ba8d083f8cbe0085a293874efdd20ff92434d8d1fcc&scene=21#wechat_redir......
  • 【笔记】二维数组在内存地址中的存储
    最近在学习STM32的ADC和DMA多通道采集过程中有使用到二维数组,姑且记录一下以作备忘。参考:http://c.biancheng.net/view/2022.html举个例子就能很简单的说明了创建一个M行N列的int数组,数组定义如下(例:M=3N=5)#defineM3#defineN5intarr[M][N];给数组按顺序赋值int(*......
  • 莫队算法学习笔记
    莫队普通莫队这个很基础。带修莫队就在普通莫队的基础上加上时间这一维度。[P1903国家集训队]数颜色/维护队列回滚莫队为什么要回滚?因为有些信息不好撤销,比如区间众数。和普通莫队相比较,就是对于每一个块,左端点放在块的右端点处,每次向左扩展,......
  • 学习笔记1 代码
    学习所用代码test.c#include<stdio.h>intmain(){printf("hello");return0;}hello.h#ifndef_HELLO_H#define_HELLO_H/***fuction:printhellostring.*parm:void*returnvalue:void*/voidsay_hello()......
  • 红日ATT&CK系列靶场(五)笔记
    环境搭建第一次登录会提示需要更改账号密码。win7账号密码:sun\heart123.comsun\Administratordc123.com—————————————————————————————————————————————————————————————2008账号密码sun\admin20......
  • 新人笔记-继承简略
    packagecom_black.jicheng;//调试类publicclassDemo{publicstaticvoidmain(String[]args){//创建对象调用方法fuc=newfu();c.show();ziz=newzi();z.method();z.show();}}packagecom_black......
  • 算法通关村第一关——链表青铜挑战笔记
    算法通关村第一关——链表青铜挑战笔记链表是一种经典的数据结构,在很多软件里大量使用,例如操作系统、JVM等。在面试中链表题目数量少,类型也相对固定,考察频率却非常高,因此我们只要将常见题目都学完就万事大吉了,所以链表特别值得刷。单链表的概念链表的概念单向链表就像一个......