connect的断线重连

connect的短线重连

  • 客户端代码的编写
  • 服务器代码的编写
  • 总结

客户端代码的编写

#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <memory>
const int defaultconnectnum = 5;
const int defaultsockfd = -1;
const int defaultconnecttime = 1;
enum class Status // C++11 强类型枚举 会进行类型转换
{NEW,          // 新建状态,就是单纯的连接CONNECTING,   // 正在连接,仅仅方便查询conn状态CONNECTED,    // 连接或者重连 成功DISCONNECTED, // 首次连接失败 进入重新连接CLOSED        // 连接失败,经历重连,无法连接
};
class Connetion
{
public:Connetion(std::string ip, uint16_t port): _status(Status::NEW),_ip(ip),_port(port),_sockfd(defaultsockfd),_connect_num(defaultconnectnum),_connet_time(defaultconnecttime){}Status get_status(){return _status;}void Connect(){int n = socket(AF_INET, SOCK_STREAM, 0);if (n < 0){std::cerr << "socker failsure!!!" << std::endl;exit(1);}_sockfd = n;// 客户端我们不用进行我们的显示bind 下面调用connectstruct sockaddr_in serve;memset(&serve, 0, sizeof(serve));serve.sin_family = AF_INET;serve.sin_port = htons(_port);// 相对与 iner_aton线程安全inet_pton(AF_INET, _ip.c_str(), &serve.sin_addr);n = connect(_sockfd, (sockaddr *)&serve, sizeof(serve));if (n < 0){// 连接失败// 此时我们把我们的sockfd关闭Close();_status = Status::DISCONNECTED;}else{_status = Status::CONNECTED;}}void ReConnect(){int count = 0;while (true){_status = Status::CONNECTING;Connect();count++;if (_status == Status::CONNECTED){std::cout << "重连成功!!!" << std::endl;break;}if (count > _connect_num){_status = Status::CLOSED;break;}std::cout << "第" << count << "次重新连接!!!" << std::endl;sleep(_connet_time);}}// 连接成功进入通信模块void Process(){// 简单的IO即可while (true){std::string inbuffer;std::cout << "Please Enter# ";getline(std::cin, inbuffer);if (inbuffer.empty())continue;ssize_t n = write(_sockfd, inbuffer.c_str(), inbuffer.size());if (n > 0){char buffer[1024];ssize_t m = read(_sockfd, buffer, sizeof(buffer) - 1);if (m > 0){buffer[m] = 0;std::cout << "echo messsge -> " << buffer << std::endl;}else if (m == 0) // 这里证明server端掉线了{_status = Status::DISCONNECTED;break;}else{std::cout << "read m : " << m << "errno: " << errno << "errno string: " << strerror(errno) << std::endl;_status = Status::CLOSED;break;}}else{std::cout << "write n : " << n << "errno: " << errno << "errno string: " << strerror(errno) << std::endl;_status = Status::CLOSED;break;}}}void Close(){if (_sockfd != -1){close(_sockfd);_status = Status::CLOSED;_sockfd = -1;}}private:Status _status;std::string _ip;uint16_t _port;int _sockfd;int _connect_num;int _connet_time;
};
class TcpClient
{
public:TcpClient(std::string ip, uint16_t port) : _ip(ip),_port(port),_conn(_ip, _port){}void Excute(){while (true){switch (_conn.get_status()){case Status::NEW:_conn.Connect();break;case Status::DISCONNECTED:_conn.ReConnect();break;case Status::CONNECTED:_conn.Process();break;case Status::CLOSED:_conn.Close();std::cout << "重连失败, 退出." << std::endl;return;default:break;}sleep(1);}}~TcpClient(){}private:std::string _ip;uint16_t _port;Connetion _conn;
};
void Usage(const std::string &process)
{std::cout << "Usage: " << process << " server_ip server_port" << std::endl;
}int main(int argc, char *argv[])
{if (argc != 3){Usage(argv[0]);}uint16_t port = std::stoi(argv[2]);std::unique_ptr<TcpClient> client = std::make_unique<TcpClient>(argv[1], port);client->Excute();return 0;
}

服务器代码的编写

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>const int BUFFER_SIZE = 1024;
const int PORT = 8081; // 默认端口int main() {// 1. 创建套接字int serverSocket = socket(AF_INET, SOCK_STREAM, 0);if (serverSocket < 0) {std::cerr << "Socket creation failed" << std::endl;return 1;}// 2. 设置SO_REUSEADDR选项int opt = 1;if (setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {std::cerr << "Set socket option failed" << std::endl;close(serverSocket);return 1;}// 3. 绑定地址sockaddr_in serverAddress;memset(&serverAddress, 0, sizeof(serverAddress));serverAddress.sin_family = AF_INET;serverAddress.sin_addr.s_addr = INADDR_ANY;serverAddress.sin_port = htons(PORT);if (bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) {std::cerr << "Bind failed" << std::endl;close(serverSocket);return 1;}// 4. 监听连接if (listen(serverSocket, 5) < 0) {std::cerr << "Listen failed" << std::endl;close(serverSocket);return 1;}std::cout << "Server listening on port " << PORT << "..." << std::endl;while (true) {// 5. 接受客户端连接sockaddr_in clientAddress;socklen_t clientAddrLen = sizeof(clientAddress);memset(&clientAddress, 0, sizeof(clientAddress));int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, &clientAddrLen);if (clientSocket < 0) {std::cerr << "Accept failed" << std::endl;continue;}char clientIP[INET_ADDRSTRLEN];inet_ntop(AF_INET, &(clientAddress.sin_addr), clientIP, INET_ADDRSTRLEN);std::cout << "Client connected: " << clientIP << ":" << ntohs(clientAddress.sin_port) << std::endl;// 6. 处理客户端请求char buffer[BUFFER_SIZE];while (true) {ssize_t bytesRead = recv(clientSocket, buffer, BUFFER_SIZE - 1, 0);if (bytesRead <= 0) {if (bytesRead == 0) {std::cout << "Client disconnected" << std::endl;} else {std::cerr << "Recv error: " << strerror(errno) << std::endl;}break;}buffer[bytesRead] = '\0';std::cout << "Received: " << buffer << std::endl;// 原样发回客户端if (send(clientSocket, buffer, bytesRead, 0) < 0) {std::cerr << "Send failed: " << strerror(errno) << std::endl;break;}}// 7. 关闭客户端套接字close(clientSocket);std::cout << "Connection closed with " << clientIP << std::endl;}// 8. 关闭服务器套接字close(serverSocket);return 0;
}

总结

通过本次客户端断线重连我们要理解我们不仅仅可以对我们的服务端进行设计我们的客户端同样如此比如客户端的收发信息我们可以设计为多线程模式等等

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

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

相关文章

通过观看数百个外科手术视频讲座来学习多模态表征|文献速递-最新论文分享

Title题目Learning multi-modal representations by watching hundreds of surgical video lectures通过观看数百个外科手术视频讲座来学习多模态表征01文献速递介绍外科计算机视觉领域的最新进展&#xff0c;已开始为手术室&#xff08;OR&#xff09;的新一代人工智能辅助支…

微信小程序如何实现再多个页面共享数据

在微信小程序中&#xff0c;实现多个页面共享数据有以下几种常用方式&#xff0c;根据场景选择最适合的方案&#xff1a; 全局变量&#xff08;App.js&#xff09; 适用场景&#xff1a;简单数据共享&#xff08;非响应式&#xff09; 实现方式&#xff1a; javascript // ap…

PCIE5.0 TAG说明(ima回答)

在PCIe 5.0规范中&#xff0c;TLP&#xff08;Transaction Layer Packet&#xff09;报文的Tag字段用于标识和管理事务。以下是关于Tag的生成和使用规则和定义的详细描述&#xff1a; Tag字段的定义 Tag字段&#xff1a;位于TLP报文的Header中&#xff0c;占用8位&#xff08…

Type-C PD快充协议智能芯片S312L详解

1. 芯片概述 S312L 是一款智能Type-C PD协议触发芯片&#xff0c;支持**PD3.0&#xff08;含PPS&#xff09;**及多种A口快充协议&#xff08;如QC/PE等&#xff09;&#xff0c;可自动识别并申请5V/9V/12V电压&#xff0c;适用于快充适配器、移动电源等场景。 核心优势&…

stm32学到什么程度可以找工作?

我重新为你写一篇更加详细深入的回答&#xff1a; STM32学到什么程度可以找工作&#xff1f;一个十年老兵的血泪史 写在前面的话&#xff1a;这些年踩过的坑&#xff0c;都是血淋淋的教训 刚看到这个问题&#xff0c;我就想起了2014年那个炎热的夏天。 当时我刚从厦门某马离…

基于 Elasticsearch 实现地图点聚合

在地图类应用中&#xff0c;当需要展示大量地理兴趣点时&#xff0c;直接将所有点渲染在地图上会导致视觉混乱&#xff0c;影响用户体验。为此&#xff0c;我基于 Elasticsearch 提供的 geotile_grid 和 geo_bounding_box 查询能力&#xff0c;实现了一套高效的 POI 聚合展示方…

【Prometheus 】通过 Pushgateway 上报指标数据

Prometheus 是目前最流行的开源监控系统之一&#xff0c;其拉取&#xff08;pull&#xff09;模型非常适合服务发现和静态目标的监控。然而&#xff0c;在某些场景下&#xff0c;例如短生命周期任务、批处理作业或无法暴露 HTTP 接口的服务&#xff0c;传统的拉取方式并不适用。…

服务器 - - QPS与TPS介绍

1、QPS&#xff08;Queries Per Second 每秒查询数&#xff09; 定义&#xff1a;常用于表示每秒的请求次数&#xff0c;衡量接口请求、数据库查询等动作的吞吐量&#xff08;单位时间内处理的数据量&#xff09; 计算&#xff1a;总请求数/请求时间&#xff0c;如&#xff1…

Cot2:思维链提示激发大型语言模型的推理能力

摘要 我们探讨了生成思维链——一系列中间推理步骤——如何显著提升大型语言模型执行复杂推理的能力。特别地&#xff0c;我们展示了在足够大的语言模型中&#xff0c;这种推理能力如何通过一种简单的方法——思维链提示&#xff08;chain-of-thought prompting&#xff09;自…

go交易数据后端

地址 https://gitee.com/EEPPEE_admin/go-stock-line-trading-datahttps://github.com/jerryshell/midas 需求 为了替代rust后端爬虫端: 爬取东方财富数据到index-data目录server端: 项目主要内容 todo 替代https://github.com/jerryshell/midas的前端量化概念性理解扩展: 存储…

灵巧手概览

第一章 灵巧手的技术演进与核心价值 1.1 技术演进的五个阶段 仿生学启蒙阶段&#xff08;1960-1980&#xff09; 1968年斯坦福大学首台3自由度机械夹爪标志机器人操作技术开端&#xff0c;1973年MIT提出"仿生手"概念&#xff0c;但受限于材料和控制技术&#xff0c;…

在设计提示词(Prompt)时,关于信息位置的安排z怎么 结合模型特性和任务目标

在设计提示词(Prompt)时,关于信息位置的安排z怎么 结合模型特性和任务目标 在设计提示词(Prompt)时,关于信息位置的安排确实需要结合模型特性和任务目标。从自注意力机制的原理及应用场景来看,关键信息的位置选择需遵循以下启示,并结合具体场景灵活调整: 一、核心启示…

七、性能优化

目录 1. 如何检测Flutter应用的性能问题&#xff1f;2. 什么是重绘边界&#xff08;Repaint Boundary&#xff09;&#xff1f;3. 如何避免不必要的重建&#xff1f;4. const 构造函数在优化中起什么作用&#xff1f;5. 如何优化长列表的性能&#xff1f;6. 如何减少应用启动时…

Webpack优化详解

Webpack 5提供了一系列工具和功能,可以在本地开发和线上构建过程中进行优化,以提高开发效率和构建性能。 1. 本地开发优化 1.1. 开启模块热替换(HMR) 模块热替换可以在不刷新整个页面的情况下更新模块,提高开发效率。 const webpack = require(webpack);module.export…

latency 对功耗的影响

文章目录 1、Connection Interval(连接间隔) vs. Latency(从机延迟)2、为什么不能完全依赖 Connection Interval?3、什么时候可以不用 Latency?4、如何正确配置?5、结论调节连接间隔(Connection Interval)确实可以直接影响通信频率和功耗,但 Latency(从机延迟)仍然…

10分钟搭建 PHP 开发环境教程

下载、安装 Xserver 下载 php 过程中如果提示需要安装 vc 运行环境&#xff0c;按照引导下载安装即可 安装 nginx 安装 Mysql 支持多个版本同时安装 下载 php 过程中如果提示需要安装 vc 运行环境&#xff0c;按照引导下载安装即可mysql 默认用户名为 root&#xff0c;默认密…

设计模式(六)

备忘录模式&#xff08;Memento Pattern&#xff09;详解 一、核心概念 备忘录模式允许在不破坏封装性的前提下&#xff0c;捕获并保存对象的内部状态&#xff0c;以便后续恢复。该模式通过三个角色实现&#xff1a; 原发器&#xff08;Originator&#xff09;&#xff1a;需…

迪杰斯特拉算法之解决单源最短路径问题

迪杰斯特拉算法 迪杰斯特拉(Dijkstra)算法是典型**最短路径算法**&#xff0c;用于计算一个结点到其它结点的最短路径。它的主要特点是以起始点为中心向外扩展(利用广度优先搜索思想)&#xff0c;直到扩展到终点。迪杰斯特拉(Dijkstra)算法最佳应用-最短路径 战争时期&#xf…

风平浪静、无事发生

2025年7月4日&#xff0c;16~25℃&#xff0c;阴雨紧急不紧急重要1.备考D1.物理备课不重要遇见&#xff1a;风平浪静、无事发生&#xff01;感受或反思&#xff1a;体检的结果收到了&#xff0c;医生建议多吃绿蔬多喝水&#xff01;多运动&#xff0c;少和喝饮料........

QtitanRibbon打造现代办公软件新体验:提升效率的专业界面解决方案

在现代办公环境中&#xff0c;无论是日常公文处理、文档编辑、任务协同还是数据分析&#xff0c;桌面办公软件仍扮演着不可替代的角色。然而&#xff0c;许多传统系统依旧使用菜单繁杂、图标混乱、交互老旧的界面&#xff0c;用户操作效率低、上手慢、满意度差。 QtitanRibbon…