05.基于 TCP 的遠程計算器:從協議設計到高并發實現

📖 目錄

  1. 📌 前言
  2. 🔍 需求分析
    • 🤔 我們需要解決哪些問題?
  3. 🎯 方案設計
    • 💡 服務器架構
  4. 🚀 什么是協議?為什么要設計協議?
    • 📌 結構化數據的傳輸問題
  5. 📌 協議定制:如何讓服務器正確解析數據?
    • ? TCP 直接傳輸的問題
    • ? 解決方案:在數據前加上長度信息
  6. 📌 序列化與反序列化:如何讓數據更容易解析?
    • 📌 什么是序列化?
    • 📌 選擇合適的序列化方式
    • 📜 通信協議設計
  7. 🔧 核心代碼解析
    • 🔹 協議封裝
    • 🔹 解析數據
    • 🔹 服務器處理請求
    • 🔹 網絡通信的實現
    • 🔹 服務器并發處理模型
    • 🔹 客戶端請求的發送與接收
  8. 🚀 還有哪些可以改進的地方?
    • 🛠 采用更高效的并發模型
    • 🔒 增加安全性
    • 📡 支持更豐富的計算功能
    • 📈 增強日志與監控
    • 🌍 讓它支持更多設備(跨平臺 & Web 訪問)

📌 1. 前言

計算機網絡的核心就是通信。遠程計算就是一個很好的例子:

  • 本地客戶端 負責發送計算請求(如 10 + 20
  • 遠程服務器 負責解析、計算,并返回結果(如 30

這個項目的目標是:實現一個基于 TCP 的遠程計算服務,讓多個客戶端同時發送計算請求,服務器解析并返回結果。


🔍 2. 需求分析

🤔 我們需要解決哪些問題?

1. 計算器的核心功能

  • 支持基本的 + - * / % 運算
  • 遠程計算,客戶端發送計算請求,服務器計算并返回結果
  • 處理異常情況(如除零)

2. 網絡通信的挑戰

  • 如何保證數據完整性?(TCP 是流式傳輸,可能會粘包)
  • 如何解析數據?(客戶端發送的 10 + 20,服務器怎么拆解?)
  • 如何支持多個客戶端?(服務器要能并發處理請求)

🎯 3. 方案設計

💡 服務器架構

[ 客戶端 ]      <--TCP-->     [ 服務器 ]|                               ||-- 用戶輸入                   |-- 解析請求|-- 發送計算式                 |-- 計算結果|-- 顯示運算結果               |-- 發送結果

🚀 4. 什么是協議?為什么要設計協議?

在計算機網絡中,不同的設備想要互相通信,就必須說同一種語言,否則就會雞同鴨講,無法理解對方的信息。而這種“語言”,在網絡編程中就被稱為協議(Protocol)

這篇文章,我們就從協議的概念出發,一步步拆解如何基于 TCP 實現一個“遠程計算器”服務,讓客戶端通過網絡發送計算請求,服務器收到請求后計算結果并返回給客戶端。


📌 5. 協議定制:如何讓服務器正確解析數據?

? TCP 直接傳輸的問題

TCP 是面向流的協議,它不會幫我們劃分數據邊界,導致以下問題:

  1. 粘包問題(多個小數據包合并)
  2. 拆包問題(一個大數據包被拆成多部分)

? 解決方案:在數據前加上長度信息

在數據包前加上 固定長度的頭部,存儲數據長度:

[數據長度][計算表達式]

📌 6. 序列化與反序列化:如何讓數據更容易解析?

📌 什么是序列化?

序列化(Serialization)就是將數據轉換為可傳輸的格式,然后在接收端反序列化(Deserialization)回原始格式。

📌 選擇合適的序列化方式

這里我們采用 JSON,因為它易讀易解析。

📜 通信協議設計

客戶端發送的 JSON 請求格式如下:

{"expr": "10+20"
}

服務器返回的 JSON 結果格式如下:

{"result": 30
}

🔧 7. 核心代碼解析

🔹 協議封裝

std::string encode_request(const std::string& expr)
{json j;j["expr"] = expr;return j.dump();
}

🔹 解析數據

std::string decode_response(const std::string& response)
{json j = json::parse(response);return j["result"].get<int>();
}

🔹 服務器處理請求

std::string process_request(const std::string& request)
{json j = json::parse(request);std::string expr = j["expr"];int result = eval(expr); // 計算表達式json response;response["result"] = result;return response.dump();
}

🔹 網絡通信的實現

void handle_client(int client_sock)
{char buffer[1024] = {0};read(client_sock, buffer, 1024);std::string response = process_request(buffer);send(client_sock, response.c_str(), response.length(), 0);close(client_sock);
}

🔹 服務器并發處理模型

void start_server()
{int server_fd = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in address;bind(server_fd, (struct sockaddr*)&address, sizeof(address));listen(server_fd, 5);while (true){int client_sock = accept(server_fd, NULL, NULL);std::thread(handle_client, client_sock).detach();}
}

🔹 客戶端請求的發送與接收

void send_request(const std::string& expr)
{int sock = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in serv_addr;connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));std::string request = encode_request(expr);send(sock, request.c_str(), request.length(), 0);char buffer[1024] = {0};read(sock, buffer, 1024);std::cout << "Server response: " << decode_response(buffer) << std::endl;close(sock);
}

最終效果

在這里插入圖片描述

🚀 8. 還有哪些可以改進的地方?

雖然我們的遠程計算器已經可以正常工作,但仍然有許多優化空間。下面列出了一些可以改進的方向,并給出大致的思路:

🛠 1. 采用更高效的并發模型

目前服務器采用多進程方式處理多個客戶端,但每次連接都會 fork() 一個子進程,進程創建和回收的開銷較大。如果連接數增加,性能可能會下降。

? 改進方向

  • 線程池:可以使用 std::thread + 線程池,避免頻繁創建/銷毀進程,提高并發能力。
  • epoll / select:基于 I/O 復用的方式,實現單進程管理多個連接,減少資源占用。
  • 協程方案:使用 libcoBoost.Asio 實現高并發的計算服務。

🔒 2. 增加安全性

目前客戶端可以隨意輸入數據,如果用戶輸入了 "100 / 0",就會導致除零異常。此外,服務器目前沒有身份驗證機制,任何人都可以連接并發送計算請求。

? 改進方向

  • 輸入校驗

    :在解析

    x op y
    

    之前,檢查運算是否合法,比如:

    if (op == '/' && y == 0) {return "ERROR: Division by zero";
    }
    
  • 身份驗證:可以添加 用戶名 + 密碼 認證,確保只有授權用戶才能訪問計算服務。

  • SQL 注入防護(如果涉及數據庫)


📡 3. 支持更豐富的計算功能

目前計算器只支持 + - * / %,如果想讓它更強大,可以擴展為數學計算引擎,支持 sin()、cos()、log()、pow() 等函數。

? 改進方向

  • 解析數學表達式:可以用 Shunting Yard Algorithm 解析復雜表達式,如 3 + 5 * (2 - 8) / sin(30)
  • 結合開源數學庫:如 ExprTk 解析數學表達式,甚至支持微積分計算。

📈 4. 增強日志與監控

目前服務器沒有日志系統,如果某個請求失敗,我們很難知道發生了什么問題

? 改進方向

  • 日志系統:使用 log4cppspdlog 記錄服務器運行狀態,方便排查問題。
  • 監控系統:可以結合 Prometheus + Grafana 監控請求數量、CPU 使用率等數據,確保服務器穩定運行。

🌍 5. 讓它支持更多設備(跨平臺 & Web 訪問)

目前我們的計算器是 C++ 客戶端 + C++ 服務器,但如果想要讓網頁、手機、Python 腳本也能調用計算服務,我們可以提供一個HTTP APIWebSocket 版本。

? 改進方向

  • RESTful API

    :讓客戶端用

    curl
    

    Python
    

    直接調用:

    GET /calculate?expr=10+2 HTTP/1.1
    
  • WebSocket 支持:讓前端網頁也能實時計算。

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

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

相關文章

大數據面試之路 (一) 數據傾斜

記錄大數據面試歷程 數據傾斜 大數據崗位 &#xff0c;數據傾斜面試必問的一個問題。 一、數據傾斜的表現與原因 表現 某個或某幾個Task執行時間過長&#xff0c;其他Task快速完成。 Spark/MapReduce作業卡在某個階段&#xff08;如reduce階段&#xff09;&#xff0c;日志顯…

僅僅使用pytorch來手撕transformer架構(3):編碼器模塊和編碼器類的實現和向前傳播

僅僅使用pytorch來手撕transformer架構(2)&#xff1a;編碼器模塊和編碼器類的實現和向前傳播 往期文章&#xff1a; 僅僅使用pytorch來手撕transformer架構(1)&#xff1a;位置編碼的類的實現和向前傳播 最適合小白入門的Transformer介紹 僅僅使用pytorch來手撕transformer…

《OpenCV》—— dlib(換臉操作)

文章目錄 dlib換臉介紹仿射變換在 dlib 換臉中的應用 換臉操作 dlib換臉介紹 dlib 換臉是基于 dlib 庫實現的一種人臉替換技術&#xff0c;以下是關于它的詳細介紹&#xff1a; 原理 人臉檢測&#xff1a;dlib 庫中包含先進的人臉檢測器&#xff0c;如基于 HOG&#xff08;方向…

機器學習中的梯度下降是什么意思?

梯度下降&#xff08;Gradient Descent&#xff09;是機器學習中一種常用的優化算法&#xff0c;用于最小化損失函數&#xff08;Loss Function&#xff09;。通過迭代調整模型參數&#xff0c;梯度下降幫助模型逐步逼近最優解&#xff0c;從而提升模型的性能。 1.核心思想 梯…

三、Docker 集群管理與應用

&#xff08;一&#xff09;項目案例 1、準備主機 &#xff08;1&#xff09;關閉防火墻&#xff0c;或者開放TCP端口2377&#xff08;用于集群管理通信&#xff09;、TCP/UPD端口7946&#xff08;用于節點之間的通信&#xff09;、UDP端口4789&#xff08;用于overlay網絡流…

網絡DNS怎么更改?

訪問速度慢或某些網站無法打開?改變網絡DNS設置可能會幫助解決這些問題。本文將詳細介紹如何更改網絡DNS&#xff0c;包括更改的原因、具體步驟。 一、為什么要更改DNS? 更改DNS的原因有很多&#xff0c;以下是一些主要的考慮因素&#xff1a;某些公共DNS服務器的響應速度比…

江科大51單片機筆記【12】DS18B20溫度傳感器(上)

寫在前言 此為博主自學江科大51單片機&#xff08;B站&#xff09;的筆記&#xff0c;方便后續重溫知識 在后面的章節中&#xff0c;為了防止篇幅過長和易于查找&#xff0c;我把一個小節分成兩部分來發&#xff0c;上章節主要是關于本節課的硬件介紹、電路圖、原理圖等理論…

基于springboot+vue的佳途旅行分享預約平臺

一、系統架構 前端&#xff1a;vue2 | element-ui | html 后端&#xff1a;springboot | mybatis-plus 環境&#xff1a;jdk1.8 | mysql | maven | node 二、代碼及數據庫 三、功能介紹 01. web端-注冊 02. web端-登錄 03. web端-系統主頁1 04. web端-系統主頁2 05. we…

【數據結構】2算法及分析

0 章節 &#xff11;&#xff0e;&#xff14;到1&#xff0e;&#xff15;小節。 掌握算法概念、特性、描述、算法性能時間復雜度和空間復雜度&#xff1b; 理解遞歸含義&#xff1f; 掌握實現遞歸的條件和時機&#xff1b; 應用簡單遞歸問題的算法設計&#xff1b; 重點 算法…

【一起學Rust | Tauri2.0框架】基于 Rust 與 Tauri 2.0 框架實現軟件開機自啟

文章目錄 前言 一、準備工作1.1 環境搭建1.2 創建 Tauri 項目1.3 添加依賴 二、實現開機自啟的基本原理2.1 開機自啟的基本概念2.2 Tauri 應用的生命周期 三、Windows 平臺實現3.1 Windows 注冊表機制3.2 實現步驟3.3 注意事項 四、Linux 平臺實現4.1 Linux systemd 服務4.2 實…

一周熱點-OpenAI 推出了 GPT-4.5,這可能是其最后一個非推理模型

在人工智能領域,大型語言模型一直是研究的熱點。OpenAI 的 GPT 系列模型在自然語言處理方面取得了顯著成就。GPT-4.5 是 OpenAI 在這一領域的又一力作,它在多個方面進行了升級和優化。 1 新模型的出現 GPT-4.5 目前作為研究預覽版發布。與 OpenAI 最近的 o1 和 o3 模型不同,…

css中的浮動

在 CSS 中&#xff0c;浮動&#xff08;float&#xff09;是一種定位元素的方式&#xff0c;它允許元素脫離正常的文檔流&#xff0c;并向左或向右移動&#xff0c;直到其邊緣碰到包含塊或者另一個浮動元素的邊緣。下面從多個方面詳細介紹 CSS 浮動&#xff1a; 一&#xff0c…

element-plus中form表單組件的使用

1.如何讓每個表單項對齊&#xff1f; 問題描述&#xff1a;如下圖&#xff0c;每個表單項的輸入框/下拉框/日期選擇器是沒有對齊的&#xff0c;我們希望它們縱向是對齊的。 解決方案&#xff1a;給el-form標簽&#xff0c;加上label-width"100px"即可。意思就是給每個…

線性搜索算法

何時使用線性搜索算法&#xff1f; 當處理一個小數據集時。當搜索存儲在連續內存中的數據集時。 線性搜索算法在什么情況下優于其他搜索算法&#xff1f; 當列表或數組未排序時&#xff0c;或者當輸入的大小相對較小時&#xff0c;首選線性搜索算法。它易于實現&#xff0c;并…

踩坑記錄:yolov5環境版本要求比較嚴苛?

在安裝yolov5環境時&#xff0c;numpy安裝失敗報錯metadata-generation-failed 報錯如下&#xff1a; Collecting numpy1.18.5 (from -r /*****/yolov5-5.0/requirements.txt (line 5))Using cached https://pypi.tuna.tsinghua.edu.cn/packages/01/1b/d3ddcabd5817be02df0e6…

Java設計模式系列:單例模式的7種實現與適用場景

一、單例模式核心價值與實現原則 1. 使用場景 全局配置類(如數據庫連接池)日志記錄器Spring默認Bean作用域硬件設備訪問(如打印機)2. 設計三原則 私有構造器:禁止外部實例化靜態實例持有:全局唯一訪問點延遲加載(可選):避免資源浪費二、七種單例實現方式深度解析 1.…

OpenManus-通過源碼方式本地運行OpenManus,含踩坑及處理方案,chrome.exe位置修改

前言&#xff1a;最近 Manus 火得一塌糊涂啊&#xff0c;OpenManus 也一夜之間爆火&#xff0c;那么作為程序員應該來嘗嘗鮮 1、前期準備 FastGithub&#xff1a;如果有科學上網且能正常訪問 github 則不需要下載此軟件&#xff0c;此軟件是提供國內直接訪問 githubGit&#…

【最新】DeepSeek 實用集成工具有那些?

deepseek 系列github倉庫地址 【主頁】deepseek-aiDeepSeek-R1DeepSeek-V3DeepSeek-VL2【本文重點介紹】awesome-deepseek-integration 注意&#xff1a;以下內容來自awesome-deepseek-integration DeepSeek 實用集成&#xff08;awesome-deepseek-integration&#xff09; 將…

開源!速度100Kb/s的有線和無線雙模ESP32S3芯片的DAP-Link調試器

開源&#xff01;速度100Kb/s的有線和無線雙模ESP32S3芯片的DAP-Link調試器 目錄 開源&#xff01;速度100Kb/s的有線和無線雙模ESP32S3芯片的DAP-Link調試器本項目未經授權&#xff0c;禁止商用&#xff01;本項目未經授權&#xff0c;禁止商用&#xff01;本項目未經授權&…

Flink測試環境Standalone模式部署實踐

1.JDK環境 參考官方文檔&#xff1a; https://nightlies.apache.org/flink/flink-docs-release-1.20/release-notes/flink-1.18/ 2.下載Flink&#xff1a;https://flink.apache.org/downloads/ 本次驗證用的是&#xff1a;https://www.apache.org/dyn/closer.lua/flink/flink…