第13章 网络 Page741~744 asio核心类 ip::tcp::socket

news2025/1/27 12:36:12

1.   ip::tcp::socket

liburl库使用"curl*" 代表socket 句柄
asio库使用ip::tcp::socket类代表TCP协议下的socket对象。

将“句柄”换成“对象”,因为asio库是不打折扣的C++库

ip::tcp::socket提供一下常用异步操作都以async开头

表13-3 tcp::socket提供的异步操作
async_connect()Start an asynchronous connect
async_read_some()Start an asynchronous read
async_wrtie_some()Start an asynchronous write

对应的注释以“Start...”开始,表明一个异步操作函数只是负责开始一件事,并不一直等到这件事情完成。

async_connect() : 主动发起一个连接请求

async_read_some() : 从该网络读一些数据,即有多少读多少

async_wrtie_some() : 向该网络写一些数据,即能写多少写多少

网络数据的传输,无论是发是收,是块是慢,相比CPU的计算速度,总是可以认为数据是在“断断续续”地流动的。

在libcurl下载新浪和搜狐网站的例子说明中,我们已经有关相关描述。带“_some”后缀的读写操作,正是用于实现“有多少处理多少”的思路。

不过,也会有许多时候程序明确知道需要读入或写出多少字节。asio提供一对自由函数,用于处理这种情况,如表13-4所列

表13-4 明确字节数的异步读写自由函数
async_read()Start an asynchronous read
async_write()Start an asynchronous write

【小提示】:“读/写”还是“接受/发送”

asio::ip::tcp:;socket也提供receive()和send()方法。入参的功能与read_some()和write_some()一样。细微差异是“receive()/send()”有另一套较少使用的重载版本。

既然是异步操作,就和C++的async()方法类似,调用时需要传入一个动作,用于在操作完成时回调,不管是读操作还是写操作,它们都需要这样一个原型的操作:

void handler(/*原型的名字无所谓*/
    const boost::system::error_code& error
	, std::size_t bytes_transferred
);

如果操作发生错误,error传入出错信息,这一点和定时器的回到操作的入参一样,其实是asio中各类回调都必须有的入参。如果操作成功,第二个入参表示本次读到或者写出多少字节。

【课堂作业】: 对比libcurl和asio网络读写回调

复习libcurl设置CURLOPT_READFUNCTION、CURLOPT_WRITEFUNCTION时所使用的原型,并与asio作对比。

作业的答案必须包含一点:libcurl所需回调用的函数带有数据,比如当读到网页数据时,libcurl回调我们设定的函数是:

size_t write_html(char* data, size_t size, size_t nmemb, void*);

第一个入参就是“char* data”就是libcurl读到的数据,通过回到交给我们处理,上例中我们将它写成一个磁盘文件;

但asio版本的回调,两个入参,一个出错时才有用,另一个只是告诉我们数据的大小。可是我们更关心的是数据呀,特别是读操作。

异步读操作:

让我们从最关心的读操作看起。成员函数async_read_some()的原型如下:

template <typename MutableBufferSequence, typename ReadHandler>
void async_read_some(const MutableBufferSequence& buffers
                    , ReadHandler handler);

 忽略模版,先看简化版:

void async_read_some(buffers, handler);

第一个入参要一个“内存块”对象,第二个入参就是前面说的handler()回调操作,可以是函数指针、可以是……

buffers的类型虽然是模版,但类型模版名称MutableBuffer透露端倪,它暗示我们这块buffers应该是“Mutable可变的”。在asio中,“可变的”内存块对象既表示其内容可被修改,也表示万一空间不足,该内存块对象还应支持扩张容量。简单滴说就是类似std::vector类型的对象。这样的要求非常合理,因为read some正意味着事先不确定这次到底能读到多少字节的数据。

用于明确读取指定字节内容的自由函数async_read()简化原型如下:

void async_read(ip::tcp::socket& socket,
                , const MutableBufferSequence& buffers
				, ReadHandler handler);

多出第一个入参,指定负责异步读的网络底层套接字socket;
重点是内部实现的读取数据过程,会反复地读取直到buffers填满或读操作出错为止。

异步写操作

async_write_some()原型如下:

template <typename ConstBufferSequequence, typename WriteHandler>
void async_write_some(const ConstBufferSequequence& buffers
                    , WriteHandler handler);

ConstBufferSequequence表明,这次要的buffer不会被修改。因为待写的数据肯定得事先准备好,
有多大,有什么内容一切都是定的。

可见对于网络读写操作所需的数据存储,asio要求用户方在发起异步操作前就自行准备好(上述入参buffers)。asio通常将直接使用该内存;libucurl则是由库创建内存,要求我们在回调操作时读出或写入。

asio的策略易用性较差,因为用户需要在异步操作发起到完成之间维护好这块内存;但性能较好,
因为减少内存复制或内存申请的次数。

用于明确写出指定字节内容的自由函数async_write()简化原型如下:

void async_write(ip::tcp::socket& socket
                , const ConstBufferSequequence& buffers
                , WriteHandler handler);

第一个入参用于指定负责异步读的网络底层套接字。内部实现的写数据过程,会负责将buffers内部的数据全部写出或操作出错为止。

异步发起连接。

async_connect()的原型为

template <typename ConnectHandler>
void async_connect(const endpoint_type& peer_endpoint
                    , ConnectHandler handler);

入参peer_endpoint是待连接的目标地址,其数据结构留到下一小节讲解。
入参handler是连接操作完成(失败或成功)后续回调的操作。连接操作不需要显式数据传递,
因此和定时器回调一样,只有error入参:

void handler(const boost::system::error_code& error);

拥有async_connect异步连接,async_read_some异步读,和async_write_some异步写的方法,
如果我们有一个ip::tcp::socket对象,就可以将连接,读,写串成异步操作链。

应用代码,io_service以及操作系统(OS)三者共同串成的,异步操作链示意图如图13-20所示:

除连接操作只需一次之外,后续的读写曹组可以根据需要各种组合。比如图中示意一写一读,实际应用也有可能是“写,写,读,读”或“读,读,写,写”。在后面“echo通信示例”,我们给出链式异步操作的实现代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1454165.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ElementUI Form:Cascader 级联选择器

ElementUI安装与使用指南 Cascader 级联选择器 点击下载learnelementuispringboot项目源码 效果图 el-cascader.vue&#xff08;Cascader 级联选择器&#xff09;页面效果图 项目里el-cascader.vue代码 <script> let id 0; export default {name: el_cascader,dat…

根据Ruoyi做二开

Ruoyi二开 前言菜单代码生成新建微服务网关添加微服务的路由 vue页面和对应的js文件js中方法的url和controller中方法的url总结 前言 之前写过一篇文章&#xff0c;若依微服务版本搭建&#xff0c;超详细&#xff0c;就介绍了怎么搭建若依微服务版本&#xff0c;我们使用若依就…

【大厂AI课学习笔记】【2.1 人工智能项目开发规划与目标】(2)项目开发周期

我们来学习项目开发的周期。 再次声明&#xff0c;本文来自腾讯AI课的学习笔记&#xff0c;图片和文字&#xff0c;仅用于大家学习&#xff0c;想了解更多知识&#xff0c;请访问腾讯云相关章节。如果争议&#xff0c;请联系作者。 今天&#xff0c;我们来学习AI项目的周期。 主…

基于python的企业编码管理系统源码【附下载】

《企业编码生成系统》程序使用说明 在PyCharm中运行《企业编码生成系统》即可进入如图1所示的系统主界面。在该界面中可以选择要使用功能对应的菜单进行不同的操作。在选择功能菜单时&#xff0c;只需要输入对应的数字即可。 图1 系统主界面 具体的操作步骤如下&#xff1a;…

如何选择阿里云服务器配置?阿里云服务器CPU内存带宽攻略

阿里云服务器配置怎么选择&#xff1f;根据实际使用场景选择&#xff0c;个人搭建网站可选2核2G配置&#xff0c;访问量大的话可以选择2核4G配置&#xff0c;企业部署Java、Python等开发环境可以选择2核8G配置&#xff0c;企业数据库、Web应用或APP可以选择4核8G配置或4核16G配…

QML | 属性特性(property)

一、属性特性 属性是对象的一个特性,可以分配一个静态的值,也可以绑定一个动态表达式。属性的值可以被其他对象读取。一般而言,属性的值也可以被其他对象修改,除非显式声明不允许这么做,也就是声明为只读属性。 1.定义属性特性 属性可以在C++中通过注册一个类的Q_PROPERT…

推荐几个漏洞扫描工具

渗透测试收集信息完成后&#xff0c;就要根据所收集的信息&#xff0c;扫描目标站点可能存在的漏洞了&#xff0c;包括我们之前提到过的如&#xff1a;SQL注入漏洞、跨站脚本漏洞、文件上传漏洞、文件包含漏洞及命令执行漏洞等&#xff0c;通过这些已知的漏洞&#xff0c;来寻找…

matlab代码--汉明码通过不同信道的误码率分析

1 前言 汉明码是在原数据中的一些固定位置&#xff0c;插入一个0&#xff08;或1&#xff09;&#xff0c;以进行奇&#xff08;或偶&#xff09;校验位&#xff0c;虽然使原数据变长&#xff0c;但可使其拥有纠错能力。能侦测并更正一个比特的错误&#xff1b;若有两个比特出…

京东平台的行业数据(数据分析报告)在哪里看?如何获取?

京东行业分析数据获取可通过以下途径&#xff1a; 京东官方不定期会发布行业白皮书或市场研究报告&#xff0c;商家可以关注京东官网、官方公众号、官方论坛等渠道获取最新发布的研究报告。 对于有技术开发能力的企业&#xff0c;可以通过申请接入京东开放平台API&#xff…

电脑竖屏显示了怎么回复原状

电脑屏幕变成这样 怎么恢复原状&#xff1f; 1、登录系统 2、在桌面上空白点击鼠标右键 3、在右键菜单中选择“屏幕分辨率”&#xff0c;左键点击打开 4、在窗口中“方向”位置选择“横向” 5、保存设置win7桌面即可恢复到正常状态

Arduino的PWM功能应用:会呼吸的灯

目录 概述 1 认识PWM 1.1 PWM原理 1.2 PWM的应用 1.3 在Arduino中使用PWM 2.硬件 2.1 硬件结构 2.2 线路连接 3 软件 3.1 编译和下载代码 3.2 详细代码 4 测试 4.1 灯的变化测试 4.2 使用逻辑分析仪看波形 概述 本文通过一个简单的案例&#xff0c;介绍Arduino中P…

Nginx 正向代理、反向代理

文章目录 前言1. 正向代理1.1 概念1.2 逻辑图1.3 使用场景 2. 反向代理2.1 概念2.2 逻辑图2.3 使用场景 前言 正向代理主要是用来解决访问限制问题&#xff1b;反向代理则是提供负载均衡、安全防护等作用 1. 正向代理 1.1 概念 正向代理是一个位于客户端和目标服务器之间的代理…

echarts图表中的基本设置参数

取消显示坐标值 axisLabel: { show: false} 取消坐标轴刻度线 axisTick: { show: false} 取消网格线 splitLine: { show: false } 去除y轴的线 //写在yAxis里面 axisLine:{show:false},axisTick:{show:false},去除y轴轴线&#xff08;背景线&#xff09; splitLine…

【PyQt】在PyQt5的界面上集成matplotlib绘制的图像

文章目录 0 前期教程1 概述2 matplotlib2.1 库导入2.2 图片的各个部分解释2.3 代码风格2.4 后端 3 集成matplotlib图像到pyqt界面中3.1 使用到的模块3.2 理解Qt Designer中的“控件提升”3.3 界面与逻辑分离的思路3.4 扩展 0 前期教程 【PyQt】PyQt5进阶——串口上位机及实时数…

[HTML]Web前端开发技术26(HTML5、CSS3、JavaScript )JavaScript基础——喵喵画网页

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;佬佬会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…

Java并发基础:ConcurrentSkipListSet全面解析!

内容概要 ConcurrentSkipListSet类在多线程环境下&#xff0c;它能够轻松应对大量的插入、删除和查找操作&#xff0c;同时保持数据的完整性和一致性&#xff0c;其内部基于跳表数据结构的实现&#xff0c;确保了即使在处理大规模数据时&#xff0c;也能具有出色的性能表现。 …

什么是抖音小店?什么是直播带货?一篇详解!

大家好&#xff0c;我是电商糖果 随着抖音卖货的火爆&#xff0c;不少朋友都有抖音卖货的想法。 但是会有很多人搞不清什么是抖音小店&#xff1f;什么是直播带货&#xff1f; 糖果这里就给大家详细讲解一下&#xff0c;看看普通人最适合做哪个。 什么是抖音小店&#xff1f…

linux系统Grafana关联zabbix显示

Grafana关联zabbix 服务器下载浏览器配置开启zabbix插件配置zabbix数据源可视化Zabbix数据 服务器下载 grafana-cli plugins list-remote grafana-cli plugins list-remote|grep -i zabbix grafana-cli plugins install alexanderzobnin-zabbix-appsystemctl restart grafana-…

Open CASCADE学习|曲线的切线

今天要实现的功能是在曲线的终点处沿切线方向延长该曲线。为了解决这个问题&#xff0c;需要求解该曲线在终点处的坐标值以及切矢量。问题转化为&#xff1a;已知曲线TopoDS_Edge aE&#xff0c;求其在终点处的坐标值及切线方向向量。 首先&#xff0c;将TopoDS_Edge对象转化为…

不同品牌和种类的电容与电感实测对比(D值、Q值、ESR、X)

最近买了个LCR电桥&#xff0c;就想测一下手头上的各种电容电感的参数&#xff0c;对比一下。 测试设备是中创ET4410&#xff0c;测量的参数有&#xff1a;电容值、电感值、D(损耗角正切值)、Q(品质因数)、ESR(等效串联电阻)、X(电抗&#xff0c;通常表示为感抗XL或容抗XC)。 …