集群聊天服務器---muduo庫的使用

使用 C++ 和 muduo 網絡庫來實現一個簡單的聊天服務器和客戶端。

服務器端:

class chatServer
{
public:// 初始化TcpServerchatServer(muduo::net::EventLoop *loop,const muduo::net::InetAddress &listenAddr): _server(loop, listenAddr, "chatServer"){// 通過綁定器設置回調函數_server.setConnectionCallback(bind(&chatServer::onConnection, this, _1));_server.setMessageCallback(bind(&chatServer::onMessage, this, _1, _2, _3));// 設置EventLoop的線程個數_server.setThreadNum(10);}// 啟動ChatServer服務void start(){_server.start();}private:// TcpServer綁定的回調函數,當有新連接或連接中斷時調用void onConnection(const muduo::net::TcpConnectionPtr &con);// TcpServer綁定的回調函數,當有新數據時調用void onMessage(const muduo::net::TcpConnectionPtr &con,muduo::net::Buffer *buf,muduo::Timestamp time);private:muduo::net::TcpServer _server;
};

首先:構造函數中

? ? ? ? 初始化TcpServer對象_server,傳入EventLoop,監聽地址和服務器名稱

? ? ? ? 設置連接和消息的回調函數,這些函數將在連接建立或者斷開時調用,以及接受到新消息時調用

? ? ? ? 設置Eventloop的線程數為10 使用10個線程來處理網絡事件

而start()方法 是為了啟用TcpServer,開始監聽和接受連接

其中私有成員:

? ? ? ? 兩個函數 分別是為了處理新連接或者連接斷開的回調函數。一個是為了處理接收到的新消息的回調函數。

? ? ? ? 私有成員的變量:_server:是TcpServer對象,是用來管理網絡連接和事件。

客戶端:

class chatClient
{
public:chatClient(muduo::net::EventLoop *loop,const muduo::net::InetAddress &addr): _client(loop, addr, "chatClient"){// 設置客戶端TCP連接回調接口_client.setConnectionCallback(bind(&chatClient::onConnection, this, _1));// 設置客戶端接收數據回調接口_client.setMessageCallback(bind(&chatClient::onMessage, this, _1, _2, _3));}// 連接服務器void connect(){_client.connect();}private:// TcpClient綁定回調函數,當連接或者斷開服務器時調用void onConnection(const muduo::net::TcpConnectionPtr &con);// TcpClient綁定回調函數,當有數據接收時調用void onMessage(const muduo::net::TcpConnectionPtr &con,muduo::net::Buffer *buf,muduo::Timestamp time);muduo::net::TcpClient _client;
};

構造函數:

????????初始化 TcpClient 對象 _client,傳入 EventLoop、服務器地址和客戶端名稱。

????????設置連接和消息的回調函數,這些函數將在連接建立或斷開時調用,以及接收到新消息時調用。

? ? ? ? connect()的作用是啟動客戶端連接到服務器。

私有成員:

? ?onConnection():處理連接或斷開服務器的回調函數。

? ?onMessage():處理接收到的新消息的回調函數。

_clientTcpClient 對象,用于管理與服務器的連接和數據傳輸。

?

網絡服務器編程常用模型

  1. 方案1:accept + read/write

    這不是并發服務器。每個連接都需要一個獨立的線程或進程來處理,不適合高并發場景。
  2. 方案2:accept + fork - process-pre-connection

    適合并發連接數不大,計算任務工作量大于fork的開銷的場景。服務器接受連接后,通過fork創建子進程來處理每個連接。
  3. 方案3:accept + thread - thread-pre-connection

    比方案2的開銷小了一點,但是并發造成線程堆積過多。服務器接受連接后,為每個連接創建一個線程來處理。
  4. 方案4:muduo的網絡設計:reactors in threads - one loop per thread

    一個main reactor負責accept連接,然后把連接分發到某個sub reactor(采用round-robin的方式來選擇sub reactor),該連接的所有操作都在那個sub reactor所在的線程中完成。多個連接可能被分派到多個線程中,以充分利用CPU。Reactor poll的大小是固定的,根據CPU的數目確定。
  5. 方案5:reactors in process - one loop pre process

    類似于Nginx服務器的網絡模塊設計,基于進程設計,采用多個Reactors充當I/O進程和工作進程,通過一把accept鎖,完美解決多個Reactors的“驚群現象”。

?

muduo中的reactor模型

? ? ? ? Reactor模型是一種事件處理模式,用于處理并發的服務請求。它可以處理一個或多個輸入源(one or more inputs),并通過服務處理器(Service Handler)將輸入事件(Event)同步分發給相應的請求處理器(Request Handler)進行處理。

  1. muduo網絡庫的模型

    • main Reactor負責監聽新的連接請求,并將新用戶連接分配給工作線程(工作線程中包含epoll)。

    • 工作線程使用epoll來處理已連接用戶的讀寫事件。

    • 對于耗時的I/O操作(如傳送文件、音視頻),可以單獨開辟線程來處理,以避免阻塞主線程。

  2. 使用多個Reactors

    • mainReactor負責接受新的客戶端連接,并將這些連接分發給subReactor

    • 每個subReactor處理一部分客戶端的讀寫、解碼、計算、編碼和發送操作。

void setConnectionCallback(const ConnectionCallback& cb)
{connectionCallback_ = cb;
}/// Set message callback.
/// Not thread safe.
void setMessageCallback(const MessageCallback& cb)
{messageCallback_ = cb;
}

?

class ChatServer
{
public:ChatServer(EventLoop *loop,  // 事件循環const InetAddress &listenAddr,  // IP+Portconst string &nameArg)  // 服務器的名字: _server(loop, listenAddr, nameArg), _loop(loop){// 給服務器注冊用戶連接的創建和斷開回調_server.setConnectionCallback(std::bind(&ChatServer::onConnection, this, _1));// 給服務器注冊用戶讀寫事件回調}private:// 專門處理用戶的連接創建和斷開 epoll listenfd acceptvoid onConnection(const TcpConnectionPtr&){}TcpServer _server;  // #1EventLoop *_loop;  // #2 epoll
};

?

  1. 構造函數

    • ChatServer類接受一個EventLoop指針、一個InetAddress對象(包含IP地址和端口號)和一個服務器名稱。

    • 使用這些參數初始化TcpServer對象_server和一個EventLoop指針_loop。并注冊連接回調函數onConnection

    • 注冊連接回調函數onConnection,當有新連接或連接斷開時調用。

  2. 私有成員變量

    • _serverTcpServer對象,用于管理網絡連接和事件。

    • _loopEventLoop指針,用于處理事件循環。


?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/910571.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/910571.shtml
英文地址,請注明出處:http://en.pswp.cn/news/910571.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

關于Net Core Web API 項目測試 數據庫模擬的兩種不同方法 DC_week 6

1.關系型數據庫 插件:Microsoft.EntityFrameworkCore.InMemory Microsoft.EntityFrameworkCore.InMemory 是一個用于測試的“臨時內存數據庫”,讓你在不連接真實數據庫的情況下,測試 EF Core 的功能。 使用時就是用具體這個框架里面已經…

如何獲取 vscode 的 vsix 離線插件安裝包

1、搜索所需要的插件 Extensions for Visual Studio family of products | Visual Studio Marketplace網址 2、點擊 Repository 跳轉到對應的 git 倉庫 3、在 git 倉庫依次選擇 main , Tags, View all tags 4、選擇你想下載的版本,并點擊 downloads 5、往下滑動&…

ULS23 挑戰:用于計算機斷層掃描中 3D 通用病變分割的基準模型及基準數據集|文獻速遞-深度學習醫療AI最新文獻

Title 題目 The ULS23 challenge: A baseline model and benchmark dataset for 3D universal lesion segmentation in computed tomography ULS23 挑戰:用于計算機斷層掃描中 3D 通用病變分割的基準模型及基準數據集 01 文獻速遞介紹 每年進行的CT檢查數量持續…

WebSocket 端點 vs Spring Bean

在websocket端點中注入業務service時,不能像普通的springbean一樣通過Autowired或Resource注解進行注入。主要原因是websocket端點與spring容器中的bean的生命周期管理容器不同。 WebSocket 端點(ServerEndpoint)和 Spring Bean 的生命周期存…

MySQL8:jdbc插入數據后獲取自增ID

pom文件&#xff1a; <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"&…

MyBatis(Web后端開發第二期)

p.s.這是萌新自己自學總結的筆記&#xff0c;如果想學習得更透徹的話還是請去看大佬的講解 目錄 JDBC、數據庫連接池、lombok日志輸出SQL注入數據封裝XML映射文件動態SQL<if><where><set><foreach><sql><include> 配置文件 Mybatis是是一…

Angular1--Hello

最近有個小錯誤&#xff0c;因為最近還是在看thingsboard&#xff0c;最近終于看到前端的代碼&#xff0c;突然發現怎么全是ts的文件&#xff0c;仔細一看原來并不是之前認為的AngularJS&#xff0c;而是Angular。。。我tm真的無語了&#xff0c;又要去重新學。。。 Angular的…

什么是redission看門狗機制

Redisson 的看門狗機制(Watchdog Mechanism)是其實現可重入分布式鎖時的一個核心特性,主要用于解決業務邏輯執行時間超過鎖的過期時間(leaseTime)而導致鎖提前釋放,進而引發數據不一致的問題。它是一個自動的鎖續期機制。 ?? 核心問題:為什么需要看門狗? 分布式鎖的…

黑馬程序員蒼穹外賣DAY1

1. 前端頁面能正常顯示但無法登錄&#xff08;一直轉圈圈&#xff09; 找到下面路徑的dev.yml port一定要跟自己本機的保持一致&#xff0c;&#xff0c;username和password也一定是自己主機的用戶名和密碼&#xff0c;不然連不上。 登錄界面的密碼為數據庫表的密碼&#xff0…

Frida Hook Android App 點擊事件實戰指南:從進程識別到成功注入

一、背景與目標 在逆向分析和自動化測試中&#xff0c;Hook Android 的點擊事件是調試 UI 交互邏輯的重要手段之一。本文將以實際案例講解如何通過 Frida Hook public void onClick(View view) 方法&#xff0c;并解決常見的 Hook 失敗問題&#xff0c;最終實現對登錄按鈕的監…

Arduino Nano 33 BLE Sense Rev 2開發板使用指南之【環境搭建 / 點燈】

一、硬件介紹 1、產品特點 Arduino Nano 33 BLE Rev2&#xff0c;利用了nRF52840微控制器的先進功能。這款32位Arm Cortex-M4 CPU 64 MHz與MicroPython的兼容性增強了板子的靈活性&#xff0c;使其更容易被更廣泛的開發者社區所接受。 該開發板的突出特點是其藍牙低功耗&…

[QT]-宏使用

用宏,務必寫清文檔并用 do {…} while (0)為啥呢,示例 在 C/C++ 中,使用 do { … } while (0) 包裹宏定義是一種經典的最佳實踐,主要用于解決宏展開后的語法和邏輯問題。以下是詳細解釋和示例: 一、為什么用 do { … } while (0) 包裹宏? 避免分號導致的語法錯誤 問題場…

python-property、反射

# ### property """ 可以把方法變成屬性 : 可以動態的控制屬性的獲取,設置,刪除相關操作 property 獲取屬性 方法名.setter 設置屬性 方法名.deleter 刪除屬性 """ # 方法一 """是同一個方法名""" class MyCla…

【自動鼠標鍵盤控制器|支持圖像識別】

[軟件名稱]: 電腦圖像識別 [軟件大小]: 57.2 MB [下載通道]: 夸克盤 | 迅雷盤 &#x1f3ae;【自動鼠標鍵盤控制器&#xff5c;支持圖像識別】基于Python開發的智能自動化工具 輕量便捷的自動化操作工具&#xff0c;集成圖像識別、鼠標控制、鍵盤模擬等功能&#xff0c;輕松…

ISO/IEC 8824規范實際應用案例

案例 1&#xff1a;X.509 數字證書&#xff08;互聯網安全基石&#xff09; 標準依據&#xff1a;RFC 5280 (基于 ASN.1 定義) 核心應用&#xff1a; Certificate :: SEQUENCE {tbsCertificate TBSCertificate, -- 證書主體signatureAlgorithm AlgorithmIdentifier,…

QT6工程各種路徑詳解

一.當前工作目錄 1.獲取方法&#xff1a; #include <QDir> qDebug() << "當前工作目錄&#xff1a;" << QDir::currentPath(); 打印結果&#xff1a; 當前工作目錄&#xff1a; "D:/2.QT/test/test_console/build/QT6_8_2_64_MSVC-Release&…

1931. 用三種不同顏色為網格涂色

1931. 用三種不同顏色為網格涂色 mod_value 10**9 7 class Solution:def colorTheGrid(self, m: int, n: int) -> int:# 1、預處理所有合法的單行涂色方案# 存儲 3^i&#xff0c;用于快速計算顏色編碼的每一位&#xff08;類似位運算&#xff09;# [3^0, 3^1, 3^2, ...,…

整數的輸入輸出

整數的輸入輸出 兩種形式輸出&#xff1a;&#xff08;以int為界&#xff09; char、short、int都用 %dlong 和long long都用 %ld %d char、short、int%ld long long long%u unsignde%lu unsignde long long 整數的格式化輸出示例 #include <stdio.h> int main(){cha…

【llm實戰】Python打造BGE模型微調服務實戰指南

1. 引言:為何需要BGE模型微調?定制化語義的力量 BGE(BAAI General Embedding)是由北京智源人工智能研究院(BAAI)發布的通用文本嵌入模型系列,因其在中英文任務上的優異表現而廣受歡迎,尤其是在MTEB(Massive Text Embedding Benchmark)等權威榜單上名列前茅。 盡管通…

代碼分析與自動化重構

PS&#xff1a;根據過去編寫 Modernizing 相關的開源工具里&#xff0c;編寫的《代碼分析與自動化重構》指南。 遺留系統的現代化演進是一門藝術。在日常的軟件開發里&#xff0c;我們經常會遇到一系列的問題&#xff1a; 如何解決人類智商不夠的問題&#xff1f;模式、原則和…