『Linux_网络』 基于状态机的Connect断线重连

        客户端会面临服务器崩溃的情况, 我们可以试着写一个客户端重连的代码, 模拟并理
解一些客户端行为, 比如游戏客户端等。

        客户端部分,我们本次采用状态机的设计模式实现

下面是关于状态机模式的介绍

状态机模式

状态机模式(State Pattern)是一种行为设计模式,它能让对象在内部状态发生改变时,改变自身的行为,给人一种对象仿佛改变了类的感觉。下面从多个方面对其进行详细介绍。

模式动机

在软件开发里,某些对象的行为会依据其状态的不同而改变。若用大量的条件语句(如 if-else 或 switch-case)来处理这些状态和行为,代码会变得复杂、难以维护和扩展。状态机模式把状态的行为封装在不同的状态类中,将状态转换逻辑和对象的其他行为分离,让代码结构更清晰,提升了可维护性和可扩展性。

模式结构

状态机模式主要包含以下几个角色:

  1. 上下文(Context):拥有一个状态对象的引用,负责与客户端交互,依据不同的情况调用状态对象的方法,并且能够在状态之间进行转换。
  2. 抽象状态(State):定义了一个接口,该接口包含了所有可能的状态行为,所有具体状态类都要实现这个接口。
  3. 具体状态(Concrete State):实现了抽象状态接口,具体实现了在该状态下的行为,并且在必要时可以改变上下文的状态。

优点

  • 可维护性:状态的行为被封装在不同的类中,使得代码的维护和扩展更加容易。
  • 可扩展性:如果需要添加新的状态,只需要创建一个新的具体状态类并实现相应的行为即可。
  • 状态转换清晰:状态转换逻辑集中在上下文类中,使得状态转换更加清晰和易于管理。

缺点

  • 类数量增加:如果状态较多,会导致类的数量增加,增加了系统的复杂度。
  • 状态转换逻辑复杂:如果状态转换逻辑复杂,上下文类中的状态转换代码可能会变得复杂。

文档编辑器样例

下面给一个给一个文件编辑器的样例,来帮助理解

假设你正在开发一个文档编辑器,文档有三种状态:草稿(Draft)、审核中(Review)和已发布(Published)。文档在不同的状态下有不同的行为,比如草稿状态可以编辑和提交审核,审核中状态可以通过审核或者打回草稿,已发布状态可以查看但不能编辑。

#include <iostream>// 前向声明
class Document;// 抽象状态类
class DocumentState {
public:virtual void edit(Document* document) {}virtual void submit(Document* document) {}virtual void approve(Document* document) {}virtual void reject(Document* document) {}virtual void view(Document* document) {}virtual ~DocumentState() {}
};// 具体状态:草稿
class DraftState : public DocumentState {
public:void edit(Document* document) override {std::cout << "文档处于草稿状态,可以编辑。" << std::endl;}void submit(Document* document) override;
};// 具体状态:审核中
class ReviewState : public DocumentState {
public:void approve(Document* document) override;void reject(Document* document) override;
};// 具体状态:已发布
class PublishedState : public DocumentState {
public:void view(Document* document) override {std::cout << "文档已发布,可以查看。" << std::endl;}
};// 上下文:文档
class Document {
private:DocumentState* state;
public:Document();~Document();void setState(DocumentState* newState);void edit();void submit();void approve();void reject();void view();
};// DraftState 类的 submit 方法实现
void DraftState::submit(Document* document) {std::cout << "文档已提交审核。" << std::endl;document->setState(new ReviewState());
}// ReviewState 类的 approve 方法实现
void ReviewState::approve(Document* document) {std::cout << "文档审核通过,已发布。" << std::endl;document->setState(new PublishedState());
}// ReviewState 类的 reject 方法实现
void ReviewState::reject(Document* document) {std::cout << "文档审核未通过,打回草稿。" << std::endl;document->setState(new DraftState());
}// Document 类的构造函数
Document::Document() {state = new DraftState();
}// Document 类的析构函数
Document::~Document() {delete state;
}// Document 类的 setState 方法
void Document::setState(DocumentState* newState) {delete state;state = newState;
}// Document 类的 edit 方法
void Document::edit() {state->edit(this);
}// Document 类的 submit 方法
void Document::submit() {state->submit(this);
}// Document 类的 approve 方法
void Document::approve() {state->approve(this);
}// Document 类的 reject 方法
void Document::reject() {state->reject(this);
}// Document 类的 view 方法
void Document::view() {state->view(this);
}int main() {Document document;document.edit();document.submit();document.approve();document.view();return 0;
}    

Connect 断线重连具体实现

Connect.hpp

 

 Client.cc

 测试Debug

测试部分,我采用我们在Linux网络篇Tcp章节所编写的翻译服务器测试以及将实现客户端与服务器通信的代码放入process中

 编译运行,服务器和客户端之间就可以进行通信了

断掉服务器,再启动服务器,重新连接的服务也是支持的 

但是我们发现每次与服务器通信,都会有一个connect success... 的提示语,那么我们怎么去掉它呢?

 首先,我们需要明确为什么每次通信都会打印这个信息

这是因为,我们服务器与客户端之间的通信循环走的是外面的这个状态判断,当状态为CONNECTED的时候,我们正常执行process代码,但当第二次循环的时候,由于我们连接状态一直是成功的,所以再执行这里的时候,还是会打印这条信息,那我们应该怎么办呢?

有两种方法,第一种在设计一种状态,就是当连接建立成功的时候,就只执行process,而不去打印这条提示语。

还记得我们之间设计的Connceting状态吗,当时说的可有可无,在这里我们就可以利用这个状态,而不用去在取名一个新的状态了。

像这样

每次进入process,就设置状态正在连接中。

在状态循环中添加这样的一条判断

编译运行,发现就没有这样的提示了

 

同样也是支持断线重连的 

 

但是这个方法也体现了状态机的一个缺点,就是状态数量的增加,状态之间的复杂性问题。

第二种方法,就是将外面的循环挪到process中,这样就不需要借助于状态判断的循环来维持服务器与客户端之间的通信了 。

实现很简单,就是在Process内部加一个循环循环条件是当前状态为connected,修改状态的时候,就可以自动退出了

 

编译运行,各种功能也是支持的

 


 至此,我们的基于状态机实现Client断线重连,就结束了。

如有什么问题,欢迎评论区留言提问。

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

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

相关文章

5月6日日记

一点心得是 看通知要仔细认真&#xff0c;自己想问的问题要先看看通知或者文件中说了没有&#xff0c;如果没说再去问相关负责人。 上课的教室一定要看好&#xff0c;看准了再去。别像今天一样先去了科技楼又去了工学馆。 线代开课了。感觉总体还行&#xff0c;并不是很难。…

【算法专题十】哈希表

文章目录 0.哈希表简介1. 两数之和1.1 题目1.2 思路1.3 代码 2.判断是否为字符重排2.1 题目2.2 思路2.3 代码 3. leetcode.217.存在重复元素3.1 题目3.2 思路3.3 代码 4. leetcode.219.存在重复的元素Ⅱ4.1 题目4.2 思路4.3 代码 5. leetcode.49.字母异位词分组5.1 题目5.2 思路…

【前缀和】矩阵区域和

文章目录 1314. 矩阵区域和解题思路1314. 矩阵区域和 1314. 矩阵区域和 ​ 给你一个 m x n 的矩阵 mat 和一个整数 k ,请你返回一个矩阵 answer ,其中每个 answer[i][j] 是所有满足下述条件的元素 mat[r][c] 的和: i - k <= r <= i + k, j - k <= c <= j + k …

MyBatis的SQL映射文件中,`#`和`$`符号的区别

在MyBatis的SQL映射文件中,#和$符号用于处理SQL语句中的参数替换,但它们的工作方式和使用场景有所不同。 #{} 符号 预编译参数:#{} 被用来作为预编译SQL语句的占位符。这意味着MyBatis会将你传入的参数设置为PreparedStatement的参数,从而防止SQL注入攻击,并允许MyBatis对…

Linux中为某个进程临时指定tmp目录

起因&#xff1a; 在linux下编译k8s&#xff0c;由于编译的中间文件太多而系统的/tmp分区设置太小&#xff0c;导致编译失败&#xff0c;但自己不想或不能更改/tmp分区大小&#xff0c;所以只能通过其他方式解决。 现象&#xff1a; tmp分区大小&#xff1a; 解决方法&#x…

Tomcat中Web应用程序停止时为了防止内存泄漏,JDBC驱动程序被强制取消注册出现原因

1.问题描述 本地Windows环境开发的Springboot项目同样的mysql版本&#xff0c;jdk版本&#xff0c;tomcat版本&#xff0c;本地运行没有任何问题&#xff0c;发布到阿里云服务器上时报以下问题&#xff1a; 06-May-2025 20:06:12.842 警告 [main] org.apache.catalina.loader…

主流国产大模型(以华为盘古大模型和腾讯混元大模型为例)API调用接口的具体参数和使用方法,包括Python和C++的示例代码

以下是主流国产大模型&#xff08;以华为盘古大模型和腾讯混元大模型为例&#xff09;API调用接口的具体参数和使用方法&#xff0c;包括Python和C的示例代码。 华为盘古大模型 API参数&#xff1a; - model&#xff1a;模型名称&#xff0c;如pangu-nlp-large。 - messages&…

高效调用京东 API 实战:商品详情页实时数据采集接口开发指南​

在当今数字化商业环境中&#xff0c;电商数据的实时获取与分析对于企业的决策制定和市场竞争力提升至关重要。京东作为国内领先的电商平台&#xff0c;提供了丰富的 API 接口&#xff0c;允许开发者高效地获取商品详情页的实时数据。本文将详细介绍如何通过实战开发&#xff0c…

MFC自定义控件开发与使用指南

MFC自定义控件开发与使用指南 自定义控件、双缓冲 1. 概述 MFC(Microsoft Foundation Classes)框架提供了丰富的内置控件,但在实际开发中,我们常常需要创建自定义控件来满足特定的界面需求。本文将详细介绍如何在MFC中开发自定义控件,并以CCustomTextControl为例,展示自…

第100+40步 ChatGPT学习:R语言实现多轮建模

回顾一下什么叫多轮建模&#xff1a; 要综合判断一个模型好不好&#xff0c;一次随机抽样是不行的&#xff0c;得多次抽样建模&#xff0c;看看整体的性能如何才行&#xff08;特别是对于这种小训练集&#xff09;。 所以我的思路是&#xff0c;随机抽取训练集和验证集2000次…

编码器型与解码器型语言模型的比较

编码器型与解码器型语言模型的比较 1. 引言 自然语言处理&#xff08;NLP&#xff09;领域近年来取得了革命性进展&#xff0c;这在很大程度上归功于基于Transformer架构的语言模型。在这一技术生态中&#xff0c;编码器型&#xff08;Encoder-only&#xff09;和解码器型&am…

python--------修改桌面文件内容

目录 1. 文件的读写1. 写入文件2. 读取文件3. 追加内容到文件 2.file_path 的常见方法1. 绝对路径2. 相对路径3. 使用 os.path 模块构建路径5. 路径操作5. 用户主目录路径 4. 修改文件内容1.将修改后的内容写回文件2. 逐行处理文件内容3. 使用上下文管理器确保文件安全 1. 文件…

爱普生VG7050EFN压控晶振在小基站的应用优势

在 5G 通信时代&#xff0c;小基站作为提升网络覆盖和容量的重要一环&#xff0c;小基站的稳定运行对于保障用户流畅的通信体验起着关键作用。而在小基站的核心组件中&#xff0c;时钟信号源的质量直接影响着通信质量和设备性能。爱普生VG7050EFN晶振凭借其高性能、小尺寸和低功…

人工智能如何革新数据可视化领域?探索未来趋势

在当今数字化时代&#xff0c;数据如同汹涌浪潮般不断涌现。据国际数据公司&#xff08;IDC&#xff09;预测&#xff0c;全球每年产生的数据量将从 2018 年的 33ZB 增长到 2025 年的 175ZB。面对如此海量的数据&#xff0c;如何有效理解和利用这些数据成为了关键问题。数据可视…

精益数据分析(42/126):移动应用商业模式的深度剖析与实战要点

精益数据分析&#xff08;42/126&#xff09;&#xff1a;移动应用商业模式的深度剖析与实战要点 在创业和数据分析的学习之路上&#xff0c;我们持续探索不同商业模式的奥秘&#xff0c;今天聚焦于移动应用商业模式。我希望和大家一起进步&#xff0c;深入解读《精益数据分析…

未来 CSS:变量、容器查询与新特性的探索

引言&#xff1a;CSS 演进与未来展望 在前端开发的快速发展浪潮中&#xff0c;CSS 已从简单的样式标记语言蜕变为构建现代设计系统的强大基础。根据 HTTP Archive 的 Web Almanac 的调查&#xff0c;超过 86% 的网站已采用至少一项现代 CSS 特性&#xff0c;这一数字仍在持续攀…

概统期末复习--速成

随机事件及其概率 加法公式 推三个的时候ABC&#xff0c;夹逼准则 减法准则 除法公式 相互独立定义 两种分析 两个解法 古典概型求概率&#xff08;排列组合&#xff09; 分步相乘、分类相加 全概率公式和贝叶斯公式 两阶段问题 第一个小概率*A在小概率的概率。。。累计 …

论微服务架构设计及应用

目录 摘要(300~330字) 正文(2000~2500字,2200字为宜) 背景介绍(500字做左右) 论点论据(1500字做左右)

【东枫科技】AMD / Xilinx Alveo™ V80计算加速器卡

AMD / Xilinx Alveo™ V80计算加速器卡 AMD/Xilinx Alveo ™ V80计算加速器卡是一款功能强大的计算加速器&#xff0c;基于7nm Versal™ 自适应SoC架构而打造。 AMD/Xilinx Alveo V80卡设计用于内存密集型任务。 这些任务包括HPC、数据分析、网络安全、传感器处理、计算存储和…

基于大模型的自然临产阴道分娩全流程预测与方案研究报告

目录 一、引言 1.1 研究背景与目的 1.2 研究意义 1.3 国内外研究现状 二、大模型技术原理与应用概述 2.1 大模型基本原理 2.2 在医疗领域的应用现状 2.3 用于分娩预测的优势 三、术前预测与准备方案 3.1 产妇身体状况评估指标 3.2 大模型预测流程与方法 3.3 基于预…