当前位置: 首页 > news >正文

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. 粘包处理机制完善:可以通过在数据传输中添加特定的消息分隔符,或者在数据头部嵌入长度标识符等方式,让接收端能够精准地识别每条消息的边界,确保数据的完整性与准确性,提升系统的可靠性。

相关文章:

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

Boost.Asio 同步读写及客户端 - 服务器实现详解 参考文献 Boost.Asio 官方文档学习资料来源: 参考网址 一、引言 Boost.Asio作为一个强大的跨平台网络编程库&#xff0c;为开发者提供了丰富的网络操作接口。在之前的学习中&#xff0c;我们已接触到其同步读写的API函数&…...

LeetCode 3019.按键变更的次数:遍历(转小写)

【LetMeFly】3019.按键变更的次数&#xff1a;遍历&#xff08;转小写&#xff09; 力扣题目链接&#xff1a;https://leetcode.cn/problems/number-of-changing-keys/ 给你一个下标从 0 开始的字符串 s &#xff0c;该字符串由用户输入。按键变更的定义是&#xff1a;使用与…...

ETCD未授权测试

一、测试环境搭建 首先拉取etcd镜像 docker pull quay.io/coreos/etcd:v3.3.1 # 查看镜像 docker images创建自定义网络 docker network create --driver bridge --subnet172.16.1.0/16 --gateway172.16.1.1 mynet # 查看网络 docker network ls创建etcd节点 节点1: docke…...

【Hystrix-1】Hystrix:构建弹性分布式系统的基石

在分布式系统的广袤星图中&#xff0c;服务间的调用如同星辰间的引力&#xff0c;维系着系统的运转。然而&#xff0c;这种依赖关系也如同达摩克利斯之剑&#xff0c;一旦某个服务出现故障&#xff0c;便可能引发连锁反应&#xff0c;导致整个系统的崩塌。Hystrix&#xff0c;如…...

【超详细】MIT 液态神经网络(LNNs)——深度学习新动向

✅作者简介:双一流博士,人工智能领域学习者,深耕机器学习,交叉学科实践者。已发表SCI1/区top论文10+,授权专利4件,公开10+。可提供专利思路和指导,提供科研小工具,分享科研经验,欢迎交流! 📌个人主页: https://blog.csdn.net/allein_STR?spm=1011.2559.3001.5343…...

Git最便捷的迁移方式

#当公司要求git需要迁移时&#xff0c;你是不是感觉到束手无策。今天带来给大家最快&#xff0c;最便捷的迁移方式 这个命令是用于重命名git仓库中的远程仓库名。在这个命令中&#xff0c;我们将远程仓库的名字从"origin"改为"old-origin"。 git remote …...

2024AAAI SCTNet论文阅读笔记

文章目录 SCTNet: Single-Branch CNN with Transformer Semantic Information for Real-Time Segmentation摘要背景创新点方法Conv-Former Block卷积注意力机制前馈网络FFN 语义信息对齐模块主干特征对齐共享解码头对齐 总体架构backbone解码器头 对齐损失 实验SOTA效果对比Cit…...

Laravel操作ElasticSearch

在Laravel项目中操作ElasticSearch可以通过以下步骤来实现&#xff0c;通常会借助相应的ElasticSearch客户端扩展包。 ### 安装ElasticSearch客户端包 在Laravel项目中&#xff0c;常用的是 elasticsearch/elasticsearch 这个PHP客户端库来与ElasticSearch进行交互&#xff0c…...

江科大STM32入门——SPI通信笔记总结

wx&#xff1a;嵌入式工程师成长日记 &#xff08;一&#xff09;简介 四根通信线&#xff1a;SCK、MOSI、MISO、SS(片选信号) 同步&#xff08;同步通信是一种通信模式&#xff0c;在这种模式下&#xff0c;发送方和接收方在同一时刻进行数据传输。&#xff09;&#xff0c;全…...

微信小程序map组件所有markers展示在视野范围内

注意&#xff1a;使用include-points属性不生效&#xff0c;要通过createMapContext实现 <template><view class"map-box"><map id"map" class"map" :markers"markers" :enable-traffic"true" :enable-poi&…...

深度解析 tanh ⁡ tanh 激活函数

1. 引言 在现代深度学习中&#xff0c;激活函数&#xff08;Activation Function&#xff09;是神经网络的核心组件之一。它的主要作用是引入非线性&#xff0c;从而使神经网络能够学习和表示复杂的非线性关系。如果没有激活函数&#xff0c;神经网络的输出将只是输入的线性组…...

嵌入式入门Day38

C Day1 第一个C程序C中的输入输出输出操作coutcin练习 命名空间使用方法自定义命名空间冲突问题 C对字符串的扩充C风格字符串的使用定义以及初始化C风格字符串与C风格字符串的转换C风格的字符串的关系运算常用的成员变量输入方法 布尔类型C对堆区空间使用的扩充作业 第一个C程序…...

探索Rancher服务发现机制:容器世界的“导航仪”

《探索Rancher服务发现机制&#xff1a;容器世界的“导航仪”》 在当今容器化技术蓬勃发展的时代&#xff0c;容器的大规模部署和微服务架构的广泛应用使得服务之间的相互发现与通信变得至关重要。Rancher作为一款功能强大的容器管理平台&#xff0c;其服务发现机制宛如一座无…...

【ROS2】Qt事件循环和ROS2订阅机制一起使用有什么注意事项?

1、简述 Qt的事件循环和ROS订阅回调函数都可能在阻塞函数中运行, 例如:Qt的QApplication::exec() 和 ROS的rclcpp::spin() 两个阻塞函数不能在同一个线程中使用,如果使用不当,会造成Qt不处理事件或者ROS2不处理订阅的回调函数。 2、多线程 一般 QApplication::exec() 运…...

donet (MVC)webAPI 的接受json 的操作

直接用对象来进行接收&#xff0c;这个方法还不错的。 public class BangdingWeiguiJiluController : ApiController{/// <summary>/// Json数据录入错误信息/// </summary>/// <param name"WeiguiInfos"></param>/// <returns></r…...

Qt 界面外观

一、前言 1、 一个完善的应用程序&#xff0c;不仅应该有实用的功能&#xff0c;还要有一个漂亮的外观&#xff0c;这样才能使应用程序更加友好&#xff0c;更加吸引用户。 2、 作为一个跨平台的UI开发框架&#xff0c;Qt提供了强大而灵活的界面外观设计机制。 3、 本篇会讲解&…...

aws(学习笔记第二十二课) 复杂的lambda应用程序(python zip打包)

aws(学习笔记第二十二课) 开发复杂的lambda应用程序(python的zip包) 学习内容&#xff1a; 练习使用CloudShell开发复杂lambda应用程序(python) 1. 练习使用CloudShell CloudShell使用背景 复杂的python的lambda程序会有许多依赖的包&#xff0c;如果不提前准备好这些python的…...

HTML课堂之搜索工具箱/讲师duluo

目录&#xff1a; 源码在最后 小提示&#xff1a; 1.养成打卡习惯没日多加练习即可提什能力 2.源码在最后&#xff0c;请先看完代码讲解&#xff0c;在尝试自己写&#xff0c;这样容易掌握 3.请勿复制粘贴&#xff0c;因为你没掌握&#xff0c;即使复制粘贴也学不会 课堂重点笔…...

当歌 - RSS 订阅分发平台开发

以下将详细介绍当歌平台的技术架构、功能实现以及相关代码逻辑。 一、项目概述 当歌是一个极简的 RSS 订阅分发平台&#xff0c;旨在为用户提供便捷的 RSS 管理和订阅服务&#xff0c;帮助用户轻松获取和分享最新资讯。 二、技术架构 后端语言&#xff1a;PHP 数据库&#…...

学习threejs,导入wrl格式的模型

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.VRMLLoader wrl模型加…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...