第13章 网络 Page749~755 asio核心类 ip::tcp::acceptor

4,ip::tcp::acceptor

ip::tcp::socket类提供用于客户端 async_connect()(发起连接)方法,但没有提供服务端
用于assync_accept()(接受连接)的方法;这正对应了客户端和服务端之间的"多对一"关系

每一个socket都可以主动发起连接,但连接的目标可以是同一个服务端; 倒过来,就是一个
服务端可以接受并拥有多个客户端发起的连接。

ip::tcp::acceptor(接收器)就负责一件事:当有新客户端发起连接请求时,acceptor
决定是否接受

接受,则建立连接,不接受则连接被扼杀在摇篮里。

ip::tcp::acceptor 类的构造函数的常用版本声明如下:

acceptor(io_service& ios, endpoint_type const& endpoint, bool reuse_addr = true);

服务端的"接受器"当然是一个I/O对象,所以第一个入参是io_service对象
第二个入参指明当前服务的监听地址endpoint
最后一个入参指明端口是否可复用,如果不懂什么意思,就取默认值
构造过程会自动执行服务端的监听(listen)动作

acceptor“接收器”最重要的方法

async_accept(),它还有一个同步版本accept(),因为很少有不在意
性能的网络服务端应用,所以我们终点讲异步版本

async_accept()又有两个常用版本,二者只差一个入参:

//版本一:三个入参
void async_accept(ip::tcp::socket& peer_socket, endpoint_type& peer_endpoint,AcceptHandler handler);//版本二;两个入参(没有peer_endpoint)
void async_accept(ip::tcp::socket& peer_socket, AcceptHandler handler);

版本二不提供第二个入参peer_endpoint, 可视为版本一的简化,我们以版本一作为讲解对象

第一个入参 peer_socket表示来自对端的网络套接字
当客户端发起连接,它会沿着网线往服务端传来一个C++变量,并且区分为传值传址两种方式。这个参数作为入参传递给async_accept()函数,此时还没有接受到任何连接请求,因此该变量
只是服务端的程序预备用来存储未来可能有的新连接

第二个入参peer_endpoint和peer_socket类似,同样是需要服务端在函数调用前,事先定义的
一个变量。等到确实有客户端新请求到来是,用它来存储客户端的地址(主机地址+端口号)

当有新连接请求时,第三个入参所代表的回调操作被触发,该回调原型为:

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

ip::tcp::resolver::async_resolve()的回调函数好歹传回了解析的结果resolver::iterator iterator,

但 ip::tcp::async_accept() 的回调又只是传回是否出错的结果,代表网络连接的那个套接字变量
peer_socket上哪儿去了?那个代表客户端地址的peer_endpoint又上哪儿去了?

在对比asio与licurl的差异时,我们就已经说过了,前者需要我们自行维护好这些数据。之前my_resolver程序在解析出ip地址后,会以客户端的身份,向该地址以及用户输入的端口所代表的目标,尝试发起连接,若成功,就输出“成功。”

DumbServer(哑巴服务器):

DumbServer类只有一个成员数据,即ip::tcp::acceptor。先看构造函数:

class DumbServer
{
public:DumbServer(boost::asio::io_service& ios, char const* host, unsigned short port): _acceptor(ios, make_endpoint(host, port)){cout << "哑巴服务运行在:" << host << " : "<< port << endl;cout << "按 Ctrl - C 退出。" << endl;}private:boost::asio::ip::tcp::acceptor _acceptor;
};

 acceptor和其他“I/O类”一样,构造时,io_service入参必须以引用方式传入,因成员“_acceptor”必须在DumbServer初始化列表中完成构造,而它需要一个io_service对象。

第二个入参服务监听的地址endpoint,此处需要通过一个工具函数make_endpoint()来创建。

DumbServer唯一的普通成员函数Start():

void Start()
{boost::asio::io_service& ios = _acceptor.get_io_service();//存储客户端发来的连接auto peer_socket = make_shared<boost::asio::ip::tcp::socket>(ios);//存储客户端的端点auto peer_endpoint = make_shared<boost::asio::ip::tcp::endpoint>();

Start()方法是要让"_acceptor"执行async_accept(...)方法。

peer_scoket和peer_endpoint都被定义为shared_ptr它们将存活着,当有新连接产生时,它们一个用来存储网络连接底下的套接字一个用来存储网络连接对端的地址;直到连接被断开不再需要时,链式传递结束,二者自动释放。

重点来了,看看async_accept()方法如何调用:

    _acceptor.async_accept(*peer_socket, *peer_endpoint, [peer_socket, peer_endpoint, this](boost::system::error_code const& err){if(err){cout << err.message() << endl;}cout << "客户端为:" <<(*peer_endpoint).address().to_string()<< " : " << (*peer_endpoint).port() << endl;//链式任务反应,确保一直在监听处理this->Start();});
}//end Start()

async_accept()前两个入参都是普通对象的应用,

第一个入参类型是“ip::tcp::socket&”,第二个是“endpoint_type const&”,我们刚刚创建shared_ptr智能指针,所以只能乖乖地分别通过‘*’取值。

这也暗示了我们,将二者传递给async_accept()函数并不是一次链式传递。

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

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

相关文章

海外媒体发稿:8个提升影响力的日韩地区媒体发稿推广策略-华媒舍

在今天的数字化时代&#xff0c;媒体发稿推广成为企业和个人增加影响力的重要方式。特别是在日韩地区&#xff0c;这个拥有庞大媒体市场和活跃社交媒体用户的地区&#xff0c;正确的推广策略将对影响力的提升起到关键作用。我们将介绍8个提升影响力的日韩地区媒体发稿推广策略。…

软件测试-功能测试-测试流程-如何进行需求评审?对于测试人员来讲,如何从测试的角度评审需求文档?

导言 产品人员编写的需求文档&#xff0c;无疑是一个项目或者一项新功能的开端。需求文档的优劣&#xff0c;直接影响开发人员的代码质量&#xff0c;更会影响到后续的测试工作。所以&#xff0c;我认为&#xff0c;需求评审对于开发质量以及测试质量至关重要&#xff0c;那么…

前端判断对象为空

一.使用JSON.stringify()方法&#xff1a; JSON.stringify() 是将一个JavaScript对象或值转换为JSON格式字符串&#xff0c;如果最终只得到一个{}&#xff0c;就说明他是一个空对象 let obj1 {}; console.log(JSON.stringify(obj1) "{}"); //true 表示为空对象l…

Python面向对象:什么是面向对象程序设计

编程范式 编程即写程序or代码&#xff0c;具体是指程序猿用特定的语法数据结构算法编写代码&#xff0c;目的是用来告诉计算机如何执行任务。 如果把编程的过程比喻为练习武功&#xff0c;那么编程范式指的就是武林中的各种流派&#xff0c;而在编程的世界里最常见的两大流派就…

微信小程序:实现微信小程序应用首页开发 (本地生活首页)

文章目录 小程序应用页面开发1、创建项目并配置项目目录结构配置导航栏效果三、配置 tabBar 效果四、轮播图实现4.1 创建轮播图数据容器4.2 定义一个请求轮播图数据的接口4.3 页面加载调用 数据请求接口 五、九宫格实现5.1 获取九宫格数据5.2 结构和样式的完善六、图片布局实现…

基于 Amazon EC2 和 Amazon Systems Manager Session Manager 的堡垒机的设计和自动化实现

1. 背景 在很多企业的技术实现中&#xff0c;由于数据安全和合规性要求&#xff0c;大部分的应用服务都部署在私有云环境或专用网络中。为了满足开发人员和运维团队从本地数据中心安全访问云上资源的需求&#xff0c;采用堡垒机作为一种有效的解决方案变得尤为重要。 堡垒机的…

Java数组的传递

Java数组的传递过程中&#xff0c;值会不会改变 最后的运行结果是 String类型的值没有改变&#xff0c;char[]类型的值改变了。char[]打印出的并不是值&#xff0c;而是地址。 public class Test1{String str new String("good");char[] ch {a,b,c};public void ch…

【漏洞复现】H3C SecParh堡垒机任意用户登录漏洞

Nx01 产品简介 H3C SecParh堡垒机是一款专业用于安全管理的堡垒机产品&#xff0c;它通过强大的访问控制功能和安全审计功能&#xff0c;实现对网络服务器的远程安全管理和监控。 Nx02 漏洞描述 H3C SecParh堡垒机的get_detail_view.php中存在任意用户登录漏洞。攻击者可以构建…

深入了解Linux设备管理:字符、块和网络设备文件

在Linux系统中&#xff0c;硬件设备被视为一种特殊的文件类型&#xff0c;即设备文件。这种独特的文件类型分为三种&#xff1a;字符设备文件、块设备文件和网络设备文件。本篇博客将深入介绍这些设备文件的概念&#xff0c;以及它们在Linux系统中的作用和应用。 字符设备文件…

Robotframework 的简介及其工作原理~

下面通过官网和网上资料来简单介绍下Robotframework及其工作原理。 官方说明&#xff1a; Robot Framework is a generic test automation framework for acceptance testing and acceptance test-driven development (ATDD). It has easy-to-use tabular test data syntax a…

CentOS 7.9如何禁止内核自动更新升级

要在 CentOS 7.9 系统中禁止内核自动更新&#xff0c;你可以通过配置 YUM&#xff08;Yellowdog Updater, Modified&#xff09;来实现。这里有几种方法可以阻止内核自动更新&#xff1a; 方法 1: 使用 exclude 选项在 YUM 配置中 编辑 YUM 的配置文件 /etc/yum.conf&#xff…

IO 流分类

一、File File 类&#xff08;磁盘操作&#xff09;可以用于表示文件和目录的信息&#xff0c;但是它不表示文件的内容。递归地列出一个目录下所有文件&#xff1a; public static void listAllFiles(File dir) {if (dir null || !dir.exists()) {return;}if (dir.isFile())…

普源(RIGOL) DHO914S示波器 简单开箱评测

普源精电(RIGOL) DHO914S 12bit数字示波器 简单开箱评测。 旧的示波器感觉不好用&#xff0c;所以换个新的&#xff0c;看中了普源的这款&#xff0c;主要看中它便携支持PD供电&#xff0c;还有伯德图功能&#xff0c;以及12bit的垂直分辨率。如果你对我上面说的点没需求&…

【C语言】Debian安装并编译内核源码

在Debian 10中安装并编译内核源码的过程如下&#xff1a; 1. 安装依赖包 首先需要确保有足够的权限来安装包。为了编译内核&#xff0c;需要有一些基础的工具和库。 sudo apt update sudo apt upgrade sudo apt install build-essential libncurses-dev bison flex libssl-d…

Linux环境部署Maven(图文详细)

目录 摘要 一、准备工作 1.检查当前环境是否安装maven 2.下载maven ​编辑 3.上传maven压缩包 4.解压maven包 5.移动到/usr/local目录下方便管理 6.配置maven环境变量 7.刷新配置文件 8.配置maven镜像仓库 9.验证是否成功 摘要 笔者Linux环境为&#xff1a;Ubuntu 2…

Vue | (一)Vue核心(下) | 尚硅谷Vue2.0+Vue3.0全套教程

文章目录 &#x1f4da;class与style绑定&#x1f4da;条件渲染&#x1f4da;列表渲染&#x1f407;基本列表&#x1f407;key的原理&#x1f407;列表过滤&#xff08;搜索&#xff09;&#x1f407;列表排序&#x1f407;Vue数据监测 &#x1f4da;收集表单数据&#x1f4da;…

ADO世界之SECOND

目录 一、ADO 排序记录 1.对数据进行排序 2.根据指定的字段名处对记录进行升序排序 3.根据指定的字段名处对记录进行降序排序 4.让用户来选择根据哪列进行排序 二、ADO 添加记录 1.向数据库中的表添加记录 2.使用 INSERT command 命令时的注意事项 3.无数据字段 三、…

C 练习实例70-求字符串长度

题目&#xff1a;写一个函数&#xff0c;求一个字符串的长度&#xff0c;在 main 函数中输入字符串&#xff0c;并输出其长度。 解答&#xff1a; #include <stdio.h> int length(char *s); int main() {int len;char str[20];printf("请输入字符串:\n");scan…

一周学会Django5 Python Web开发-Django5路由定义

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计22条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

【数据库】日常使用PL/SQL 登录ORACLE 数据库查询数据

一、PL/SQL 登录方式 username&#xff1a; ##访问数据库的账号 password&#xff1a; ##访问数据库的密码 Databse&#xff1a; ##数据库IP地址/实例名 & 数据库集群心跳地址/实例名 Connect as : ##Normal&#xff0c;如果使用sysdba账户登录选择SYSDBA 二、PL/SQL使用…