Boost.Asio 同步读写及客户端 - 服务器实现详解

Boost.Asio 同步读写及客户端 - 服务器实现详解

参考文献

  1. Boost.Asio 官方文档
  2. 学习资料来源: 参考网址

一、引言

Boost.Asio作为一个强大的跨平台网络编程库,为开发者提供了丰富的网络操作接口。在之前的学习中,我们已接触到其同步读写的API函数,本文将在此基础上,深入探讨如何运用这些API构建一个完整且能实际运行的客户端与服务器示例,且双方均采用阻塞式的同步读写方式来实现通信。

二、客户端设计

  1. 设计思路
    • 首要任务是依据服务器的IP地址与端口号构建一个 endpoint,这是后续连接的目标定位信息。
    • 借助 socket 对象,向已确定的 endpoint 发起连接请求,尝试与服务器建立通信链路。
    • 成功连接后,运用同步读写机制,实现向服务器发送数据以及接收服务器响应数据的功能。
  2. 代码剖析
#include <iostream>
#include <boost/asio.hpp>
using namespace std;
using namespace boost::asio::ip;
const int MAX_LENGTH = 1024;int main() {try {// 1. 初始化Boost.Asio的核心对象io_context,它为后续的网络操作提供运行环境boost::asio::io_context ioc;// 2. 构建远程服务器的endpoint,明确通信目标的IP与端口,这里以本地回环地址127.0.0.1及端口10086为例tcp::endpoint remote_ep(address::from_string("127.0.0.1"), 10086);// 3. 创建用于网络通信的socket对象,绑定到之前创建的io_contexttcp::socket sock(ioc);// 4. 向服务器发起连接请求,并通过error_code检查连接结果boost::system::error_code error = boost::asio::error::host_not_found;sock.connect(remote_ep, error);// 若连接失败,输出错误详情并终止程序if (error) {cout << "连接失败,错误代码: " << error.value() << " 错误信息: " << error.message() << endl;return 0;}// 5. 提示用户输入要发送给服务器的消息std::cout << "请输入消息: ";char request[MAX_LENGTH];std::cin.getline(request, MAX_LENGTH);// 6. 计算输入消息的长度,并通过Boost.Asio的write函数将消息发送至服务器size_t request_length = strlen(request);boost::asio::write(sock, boost::asio::buffer(request, request_length));// 7. 准备接收服务器的回复,利用read函数从socket读取数据至reply缓冲区char reply[MAX_LENGTH];size_t reply_length = boost::asio::read(sock,boost::asio::buffer(reply, request_length));// 8. 输出服务器的回复内容std::cout << "服务器回复: ";std::cout.write(reply, reply_length);std::cout << "\n";}catch (std::exception& e) {// 捕获并处理任何可能出现的异常,输出错误信息std::cerr << "发生异常: " << e.what() << endl;}return 0;
}

三、服务器设计

服务器端的设计相对复杂,主要由两个关键函数协同完成工作。

  1. session 函数
    • 功能定位:此函数专门负责处理单个客户端的连接请求。每当服务器监听到有新客户端接入时,便会立即调用该函数,对客户端的数据交互进行管理。
    • 实现逻辑:采用循环结构,持续监听客户端发送的数据。一旦接收到数据,首先检查错误状态,若客户端正常关闭连接,函数能及时察觉并结束循环;若出现其他错误,则抛出异常。对于接收到的有效数据,不仅会在服务器端打印出来源客户端的IP地址以及消息内容,还会将数据原封不动地回传给客户端,实现简单的“echo”功能。
    • 代码详情
void session(std::shared_ptr<tcp::socket> sock) {try {for (;;) {char data[MAX_LENGTH];memset(data, '\0', MAX_LENGTH); // 初始化缓冲区,确保数据干净// 从客户端socket读取数据,同时关注可能出现的错误boost::system::error_code error;size_t length = sock->read_some(boost::asio::buffer(data, MAX_LENGTH), error);// 根据不同的错误情况进行相应处理if (error == boost::asio::error::eof) {std::cout << "连接被客户端关闭" << endl;break;} else if (error) {throw boost::system::system_error(error);}// 打印客户端连接信息及发送的消息std::cout << "收到来自 " << sock->remote_endpoint().address().to_string() << " 的消息" << endl;std::cout << "消息内容: " << data << endl;// 将接收到的消息原样回传给客户端boost::asio::write(*sock, boost::asio::buffer(data, length));}}catch (std::exception& e) {// 捕获并处理线程内出现的异常,输出错误详情std::cerr << "线程中发生异常: " << e.what() << "\n" << std::endl;}
}
  1. server 函数
    • 功能定位:作为服务器的启动与管理核心,负责创建服务器的监听机制,并协调客户端连接的处理流程。
    • 实现逻辑:首先创建一个 acceptor 对象,绑定到指定的IP地址与端口,开始监听客户端的连接请求。进入无限循环后,每当有新客户端连接到来,便创建一个新的 socket 对象用于与该客户端通信,并立即启动一个独立的线程,在线程中调用 session 函数处理与该客户端的交互,同时将线程分离,使其能够独立运行,避免主线程阻塞。
    • 代码详情
void server(boost::asio::io_context& io_context, unsigned short port) {// 创建acceptor,用于监听指定端口的客户端连接tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), port));for (;;) {// 为新连接创建socket对象std::shared_ptr<tcp::socket> socket(new tcp::socket(io_context));acceptor.accept(*socket); // 接受客户端连接// 为每个连接创建独立线程处理通信,分离线程以独立运行auto t = std::make_shared<std::thread>(session, socket);t->detach(); }
}
  1. 多线程处理优势:通过为每个客户端连接分配独立的线程,并在其中进行读写操作,确保了服务器的 acceptor 能够持续监听新连接,不会因某个连接的阻塞读写操作而陷入停滞,有效提升了服务器的并发处理能力。

四、同步读写的特性剖析

  1. 优点
    • 编程简易性:同步读写模式下,代码逻辑呈现顺序执行的特点,开发者无需处理复杂的异步回调嵌套,编写过程清晰明了,对于初学者或是处理简单网络场景的项目而言,上手难度较低,易于快速实现功能。
    • 维护便利性:由于代码按照线性顺序执行,没有异步操作带来的回调函数分散在各处的问题,程序的逻辑流易于追踪与理解,后续的代码维护与调试工作相对轻松。
  2. 缺点
    • 阻塞隐患:在服务器端,若客户端未能及时发送数据, read 操作将会使线程陷入阻塞状态,白白消耗系统资源,直到有数据可读为止,这在高并发场景下极易引发性能瓶颈。
    • 线程资源受限:鉴于每个连接都需要独立的线程来维持同步读写操作,而操作系统对线程数量存在上限限制(例如Linux系统默认2048个线程),当连接数大量增加时,系统可能无法创建足够的线程,导致新连接无法及时处理。
    • 线程切换成本:大量线程的频繁切换会消耗大量的CPU时间用于上下文保存与恢复,使得系统用于实际业务处理的资源被削减,整体性能受到负面影响。
    • 粘包问题未解决:无论是客户端还是服务器端,当前的同步读写实现都没有考虑到TCP协议在数据传输过程中可能出现的粘包现象,这可能导致接收端无法准确识别消息边界,造成数据解析错误。

五、改进方向展望

为克服同步读写的固有缺陷,引入异步读写模式成为必然选择:

  1. 并发性能飞跃:异步操作允许在等待数据读写完成的过程中,CPU能够转而处理其他任务,避免线程阻塞,从而能够在相同硬件资源下承载更多的客户端连接,大幅提升服务器的并发处理能力。
  2. 全双工通信优势:发送与接收数据的过程相互独立,不再受限于同步模式下的先后顺序,能够更好地适应复杂多变的通信需求,例如实时双向数据交互的场景。
  3. 粘包处理机制完善:可以通过在数据传输中添加特定的消息分隔符,或者在数据头部嵌入长度标识符等方式,让接收端能够精准地识别每条消息的边界,确保数据的完整性与准确性,提升系统的可靠性。

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

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

相关文章

Linux服务器网络不通问题排查及常用命令使用

在PVE主机上创建虚拟机&#xff0c;并配置静态ip和dns后&#xff0c;主机可以正常访问网络&#xff0c;但是在宿主机或者其他机器上都无法访问该虚拟机。 检查ip是否联通且端口是否开启 如果ip无法ping通&#xff0c;可能是静态ip配置、网卡或桥接设置问题。 [k8slocalhost …

道品科技智慧农业与云平台:未来农业的变革之路

随着全球人口的不断增长&#xff0c;农业面临着前所未有的挑战。如何在有限的土地和资源上提高农业生产效率&#xff0c;成为了各国政府和农业从业者亟待解决的问题。智慧农业的兴起&#xff0c;结合云平台的应用&#xff0c;为农业的可持续发展提供了新的解决方案。 ## 一、智…

《C++11》右值引用深度解析:性能优化的秘密武器

C11引入了一个新的概念——右值引用&#xff0c;这是一个相当深奥且重要的概念。为了理解右值引用&#xff0c;我们需要先理解左值和右值的概念&#xff0c;然后再理解左值引用和右值引用。本文将详细解析这些概念&#xff0c;并通过实例进行说明&#xff0c;以揭示右值引用如何…

【OJ刷题】同向双指针问题

这里是阿川的博客&#xff0c;祝您变得更强 ✨ 个人主页&#xff1a;在线OJ的阿川 &#x1f496;文章专栏&#xff1a;OJ刷题入门到进阶 &#x1f30f;代码仓库&#xff1a; 写在开头 现在您看到的是我的结论或想法&#xff0c;但在这背后凝结了大量的思考、经验和讨论 目录 1…

RK3562编译Android13 ROOT固件教程,触觉智能开发板演示

本文介绍编译Android13 ROOT权限固件的方法&#xff0c;触觉智能RK3562开发板演示&#xff0c;搭载4核A53处理器&#xff0c;主频高达2.0GHz&#xff1b;内置独立1Tops算力NPU&#xff0c;可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。 关闭seli…

用户界面的UML建模11

然而&#xff0c;在用户界面方面&#xff0c;重要的是要了解《boundary》类是如何与这个异常分层结构进行关联的。 《exception》类的对象可以作为《control》类的对象。因此&#xff0c;《exception》类能够聚合《boundary》类。 参见图12&#xff0c;《exception》Database…

【大模型】百度千帆大模型对接LangChain使用详解

目录 一、前言 二、LangChain架构与核心组件 2.1 LangChain 核心架构 2.2 LangChain 核心组件 三、环境准备 3.1 前置准备 3.1.1 创建应用并获取apikey 3.1.2 开通付费功能 3.2 获取LangChain文档 3.3 安装LangChain依赖包 四、百度千帆大模型对接 LangChain 4.1 LL…

用Python实现简单的任务自动化

目录 1. 自动发送邮件提醒 2. 自动备份文件 3. 自动下载网页内容 总结 在现代工作和生活中,任务自动化可以极大地提高效率和准确性。Python,作为一种功能强大且易于学习的编程语言,是实现任务自动化的理想选择。本文将通过几个简单而实用的案例,展示如何用Python实现任…

用JAVA编写一个简单的小游戏

用Java语言编写一个简单的小游戏。这里是一个非常基础的猜数字小游戏的代码示例。在这个游戏中&#xff0c;程序会随机选择一个1到100之间的整数&#xff0c;玩家需要猜测这个数字是什么。每次猜测后&#xff0c;程序会告诉玩家他们猜的数字是太高了、太低了还是正确。 impor…

腾讯云AI代码助手编程挑战赛-凯撒密码解码编码器

作品简介 在CTFer选手比赛做crypto的题目时&#xff0c;一些题目需要自己去解密&#xff0c;但是解密的工具大部分在线上&#xff0c;而在比赛过程中大部分又是无网环境&#xff0c;所以根据要求做了这个工具 技术架构 python语言的tk库来完成的GUI页面设计&#xff0c;通过…

MATLAB深度学习实战文字识别

文章目录 前言视频演示效果1.DB文字定位环境配置安装教程与资源说明1.1 DB概述1.2 DB算法原理1.2.1 整体框架1.2.2 特征提取网络Resnet1.2.3 自适应阈值1.2.4 文字区域标注生成1.2.5 DB文字定位模型训练 2.CRNN文字识别2.1 CRNN概述2.2 CRNN原理2.2.1 CRNN网络架构实现2.2.2 CN…

EXCEL: (二) 常用图表

10. 图表 134-添加.删除图表元素 图表很少是一个单独的整体&#xff0c;而是由十几种元素/对象拼凑出来的。 学习图表就是学习当中各类元素的插删改。 ①图表中主要元素的定义 图表上的一个颜色就是一个系列。 横轴是分类轴&#xff0c;将每个系列都分为几类。 ②选中图…

晨辉面试抽签和评分管理系统之一:考生信息管理和编排

晨辉面试抽签和评分管理系统&#xff08;下载地址:www.chenhuisoft.cn&#xff09;是公务员招录面试、教师资格考试面试、企业招录面试等各类面试通用的考生编排、考生入场抽签、候考室倒计时管理、面试考官抽签、面试评分记录和成绩核算的面试全流程信息化管理软件。提供了考生…

c++类和对象---上

文章目录 类的介绍 类的声明 1.1 类名 1.2 成员变量 1.3 成员函数 1.4 访问权限 类的定义 2.1 成员变量的初始化 2.2 成员函数的实现 对象的创建和销毁 3.1 默认构造函数 3.2 析构函数 3.3 拷贝构造函数 3.4 对象的实例化 3.5 对象的销毁 成员访问控制 4.1 公有成员 4.2 私有…

UI自动化测试保姆级教程--pytest详解(精简易懂)

欢迎来到啊妮莫的学习小屋 别让过去的悲伤&#xff0c;毁掉当下的快乐一《借东西的小人阿莉埃蒂》 简介 pytest是一个用于Python的测试框架, 支持简单的单元测试和复杂的功能测试. 和Python自带的UnitTest框架类似, 但是相比于UnitTest更加简洁, 效率更高. 特点 非常容易上手…

关于Mac使用VSCode连接虚拟机

1. 下载插件 输入Remote - SSH下载下图两个插件。 2. 配置虚拟机信息 按图示步骤点击完成后&#xff0c;进入到虚拟主机的配置页面。 其中Host可以自定义主机名&#xff0c;HostName是虚拟机ip&#xff0c;可以通过ifconfig eth0查看ip&#xff0c;User是虚拟机的用户名。…

细说STM32F407单片机以轮询方式读写外部SRAM的方法

目录 一、实例的功能 二、工程配置 1、KEYLED 2、时钟、DEBUG、USART6、NVIC、GPIO、CodeGenerator 3、FSMC &#xff08;1&#xff09; 模式设置 &#xff08;2&#xff09; Bank 1子区3参数设置 1) NOR/PSRAM control组&#xff0c;子区控制参数 2) NOR/PSRAM timi…

Eclipse配置Tomcat服务器(最全图文详解)

前言&#xff1a; 本章使用图文讲解如何在Eclipse开发工具中配置Tomcat服务器、如何创建和启动JavaWeb工程&#xff0c;欢迎童鞋们互相交流。觉得不错可以三连订阅喔。 目标&#xff1a; 一、配置Tomcat服务器 1. 切换Eclipse视图 2. 打开菜单 3. 找到服务选项 4. 选择…

uniapp vue2版本如何设置i18n

如何设置i18n在该软件设置过语言的情况下优先选择所设置语言&#xff0c;在没有设置的情况下&#xff0c;获取本系统默认语言就&#xff0c;将系统默认语言设置为当前选择语言。 1、下载依赖&#xff1a; npm install vue-i18n --save 2、创建相关文件&#xff08;在最外层&…

QPS和TPS 的区别是什么?QPS 大了会有什么问题,怎么解决?

QPS 和 TPS 的区别是什么&#xff1f;QPS 大了会有什么问题&#xff0c;怎么解决&#xff1f; QPS&#xff08;Queries Per Second&#xff09;和 TPS&#xff08;Transactions Per Second&#xff09;都是衡量系统性能的重要指标&#xff0c;尤其是在 Web 服务、数据库和分布…