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
英文地址,請注明出處:http://en.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…