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

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.rhkb.cn/news/259274.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端技巧之svg精灵图svg-sprite-loader

首先说明精灵图的必要性&#xff0c;其可以让我们只需要向服务器请求一次图片资源&#xff0c;就能加载很多图片&#xff0c;即能够减轻http请求造成的服务器压力。 然后这里要说明的是这个插件是webpack上面的&#xff0c;所以在vue2中比较好用&#xff0c;如果在vue3中&…

【python】网络爬虫与信息提取--正则表达式

一、正则表达式 正则表达式是用来简洁表达一组字符串的表达式。是通用的字符串表达框架&#xff0c;简洁表达一组字符串的表达式&#xff0c;针对字符串表达“简洁”和“特征”思想的工具&#xff0c;判断某字符串的特征归属。 用处&#xff1a;表达文本类型的特征&#xff1b;…

用Python和OpenCV搭建自己的一维码和QRCode扫描仪(步骤 + 源码)

导 读 本文主要介绍使用Python和OpenCV搭建自己的一维码和QRCode扫描仪&#xff08;步骤 源码&#xff09;。 项目简介 本文我们将创建一个程序来扫描图像中的二维码和条形码。对于这个程序&#xff0c;我们需要三个包&#xff0c;分别是OpenCV、NumPy和pyzbar。大多数 Pyth…

应用回归分析:岭回归

岭回归&#xff0c;也称为Tikhonov正则化&#xff0c;是一种专门用于处理多重共线性问题的回归分析技术。多重共线性是指模型中的自变量高度相关&#xff0c;这种高度的相关性会导致普通最小二乘法&#xff08;OLS&#xff09;估计的回归系数变得非常不稳定&#xff0c;甚至无法…

中科院一区论文复现,改进蜣螂算法,Fuch映射+反向学习+自适应步长+随机差分变异,MATLAB代码...

本期文章复现一篇发表于2024年来自中科院一区TOP顶刊《Energy》的改进蜣螂算法。 论文引用如下&#xff1a; Li Y, Sun K, Yao Q, et al. A dual-optimization wind speed forecasting model based on deep learning and improved dung beetle optimization algorithm[J]. Ener…

21种matlab信号分解方法汇总

21中信号分解方法汇总 CEEMD(互补集合经验模态分解)CEEMDAN(自适应噪声完备集合经验模态分解) EEMD(集合经验模态分解&#xff09;EMD(经验模态分解)ESMD(极点对称模态分解&#xff09;EWT(经验小波变换分解)FEEMD(快速EEMD分解)ICEEMDAN(改进自适应噪声完备集合经验模态分解)L…

vtk三维场景基本要素 灯光、相机、颜色、纹理映射 简介

整理一下VTK 三维场景基本要素&#xff0c;后面会一一进行整理&#xff1b; 1. 灯光 vtkLight 剧场里有各式各样的灯光&#xff0c;三维渲染场景中也一样&#xff0c;可以有多个灯光存在。灯光和相机 是三维渲染场景必备的要素&#xff0c;vtkRenderer会自动创建默认的灯光和…

Qt实用技巧:QCustomPlot做北斗GPS显示绝对位置运动轨迹和相对位置运动轨迹图的时,使图按照输入点顺序连曲线

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/136131310 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

Pulsar-架构与设计

Pulsar架构与设计 一、背景和起源二、框架概述1.设计特点2.框架适用场景 三、架构图1.Broker2.持久化存储&#xff08;Persistent storage&#xff09;3.Pulsar元数据&#xff08;Metadata store&#xff09; 四、功能特性1.消息顺序性2.消息回溯3.消息去重4.消息重投递5.消息重…

DTAN: Diffusion-based Text Attention Network for medical imagesegmentation

DTAN:基于扩散的医学图像分割文本关注网络 摘要 在当今时代&#xff0c;扩散模型已经成为医学图像分割领域的一股开创性力量。在此背景下&#xff0c;我们引入了弥散文本注意网络(Diffusion text - attention Network, DTAN)&#xff0c;这是一个开创性的分割框架&#xff0c…

动态代理IP如何选择?

IP地址是由IP协议所提供的一种统一的地址格式&#xff0c;通过为每一个网络和每一台主机分配逻辑地址的方式来屏蔽物理地址的差异。根据IP地址的分配方式&#xff0c;IP可以分为动态IP与静态IP两种。对于大部分用户而言&#xff0c;日常使用的IP地址均为动态IP地址。从代理IP的…

报错405(errAxiosError: Request failed with status code 405)

errAxiosError: Request failed with status code 405 前端调用接口的方法跟后台定义接口的方法不一致

AB测试最小样本量

1.AB实验过程 常见的AB实验过程&#xff0c;分流-->实验-->数据分析-->决策&#xff1a;分流&#xff1a;用户被随机均匀的分为不同的组实验&#xff1a;同一组内的用户在实验期间使用相同的策略&#xff0c;不同组的用户使用相同或不同的策略。数据收集&#xff1a;…

Java+Vue+MySQL,国产动漫网站全栈升级

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

算法刷题:无重复字符的最长字串

无重复字符的最长字串 .题目链接题目详情算法原理题目解析滑动窗口定义指针进窗口判断出窗口更新结果 我的答案 . 题目链接 无重复字符的最长字串 题目详情 算法原理 题目解析 首先,为了使字符串遍历的更加方便,我们选择将字符串转换为数组 题目要求子串中不能有重复的字符…

Springboot+vue的物流管理系统(有报告)。Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的物流管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的物流管理系统&#xff0c;采用M&#xff08;model&#xff09;…

~汉诺塔~(C语言)~

引言 汉诺塔&#xff08;Hanoi Tower&#xff09;&#xff0c;又称河内塔&#xff0c;源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子&#xff0c;在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从上面开始按大小顺序重新摆放在…

C++之Easyx——图形库的基本准备工作

什么是Easyx&#xff1f; EasyX Graphics Library 是针对 Visual C 的免费绘图库&#xff0c;支持 VC6.0 ~ VC2022&#xff0c;简单易用&#xff0c;学习成本极低&#xff0c;应用领域广泛。目前已有许多大学将 EasyX 应用在教学当中。 它比Red PandaDev C上的图形库功能要强…

BUGKU-WEB 变量1

题目描述 题目截图如下&#xff1a; 进入场景看看&#xff1a; flag In the variable !<?php error_reporting(0); include "flag1.php"; highlight_file(__file__); if(isset($_GET[args])){$args $_GET[args];if(!preg_match("/^\w$/",$args…

究极小白如何自己搭建一个自动发卡网站-独角数卡

首页 | 十画IOSID​shihuaid.cn/​编辑 如果你也是跟我一样,什么都不懂,也想要搭建一个自己的自动发卡网站,可以参考一下我的步骤,不难,主要就是细心,一步步来一定成功!! 独角数卡: 举个例子:独角数卡就是一个店面,而且里面帮你装修好了,而你要做的就是把开店之…