解決網絡傳輸中可能出現的“粘包”

先理解核心問題:什么是“TCP粘包”?

TCP 就像一條水管,數據通過水管從一端傳到另一端。但它有個特點:不會按“發送時的小包”來劃分,而是把數據當成連續的字節流
比如:

  • 你分兩次發數據:第一次發“hello”(5字節),第二次發“world”(5字節);
  • 接收方可能一次收到“helloworld”(10字節,兩個包粘在一起),也可能第一次收到“hel”(3字節),第二次收到“loworld”(7字節)。

這種“數據沒按預期分成小包,要么粘在一起,要么被拆成碎塊”的情況,就叫 “粘包”。如果直接用普通的 read 函數,可能讀不全或讀多了,導致數據解析錯誤。

寫個 Readn 函數:保證“讀夠指定的字節數”

不管數據是粘在一起還是被拆成碎塊,Readn 都能確保你讀到 “正好想要的字節數”。比如你要讀10字節,它就一直等,直到湊夠10字節才返回。

逐行說明:

ssize_t Readn(int fd, void* buf, size_t n) 
// 參數:fd(要讀的連接,比如客戶端連接);buf(裝數據的緩沖區);n(要讀的字節數,比如10)
{size_t nleft = n;  // 記錄“還剩多少字節沒讀”(一開始等于n,比如10)while(nleft > 0) {  // 只要還有沒讀完的,就繼續循環// 調用系統的read函數,試著讀剩下的字節(nleft)ssize_t nread = read(fd, buf, nleft);if(nread < 0) {  // 讀數據出錯了if(errno == EINTR) continue;  // 如果是“被信號打斷”(比如系統臨時有事),就重試return -1;  // 其他錯誤(比如連接斷了),返回-1表示失敗}// 讀到了nread字節(比如第一次讀了3字節)buf = (char*)buf + nread;  // 緩沖區指針往后移nread位(下次從新位置開始裝)nleft -= nread;  // 剩余字節數減少nread(比如10-3=7,還剩7字節要讀)}return n;  // 循環結束,說明讀夠了n字節,返回總字節數
}

舉例說明:怎么解決粘包?

比如你要從客戶端讀10字節數據,可能遇到兩種情況:

  1. 數據被拆成多段

    • 第一次 read 只讀到3字節,nleft 變成7,繼續循環;
    • 第二次 read 讀到5字節,nleft 變成2,繼續循環;
    • 第三次 read 讀到2字節,nleft 變成0,循環結束,返回10(成功讀夠)。
  2. 數據粘在一起

    • 第一次 read 就讀到15字節(比需要的10字節多),但 Readn 只取前10字節,nleft 變成0,循環結束,剩下的5字節會留給下一次讀取。

總結:

Readn 就像一個“執著的收快遞員”:你說要10個包裹,它就一直等,哪怕快遞分好幾次到,也會湊齊10個再交給你,絕不會少給;如果快遞多送了,就先收下需要的10個,剩下的下次再處理。

這樣就能完美解決TCP粘包問題,確保程序讀到的數據是完整、準確的,不會因為傳輸時的“拆包”“粘包”導致解析錯誤。

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

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

相關文章

Docker搭建RSS訂閱服務(freshRss+rsshub)

目錄搭建freshRss1. 創建yml文件2. 創建容器3. 檢查容器狀態&#xff0c;正常運行則搭建成功4. 瀏覽器訪問并配置數據庫5. 開始使用搭建RssHub1. 創建yml文件2. 創建容器3. 檢查容器狀態&#xff0c;正常運行則搭建成功4. 瀏覽器訪問生成RSS路由&#xff08;訂閱地址&#xff0…

Spring 條件注解與 SPI 機制(深度解析)

在 Spring 及 Spring Boot 框架中&#xff0c;條件注解與 SPI 機制扮演著至關重要的角色&#xff0c;它們是實現自動配置、靈活控制 Bean 創建以及組件按需加載的關鍵所在。深入理解它們的底層實現與應用場景&#xff0c;既能幫助我們在面試中對答如流&#xff0c;又能在實際開…

Mac(二)Homebrew 的安裝和使用

官網地址&#xff1a; https://brew.sh/官方文檔&#xff1a; https://docs.brew.sh/Manpage Homebrew 是 macOS 上最強大的包管理器&#xff0c;讓你輕松安裝、更新和管理成千上萬的開發工具、命令行程序&#xff08;如 wget, tree, ffmpeg&#xff09;甚至圖形應用&#xff0…

Vue 偵聽器(watch 與 watchEffect)全解析2

二、watchEffect:自動追蹤依賴的偵聽器 watchEffect 是更“簡潔”的偵聽器:它不需要手動指定數據源,而是自動追蹤回調中用到的響應式狀態——當這些狀態變化時,自動觸發回調。適用于“副作用與依賴綁定緊密”的場景(如依賴較多、無需區分新舊值)。 1. 基本用法(與 wat…

正點原子STM32H743配置 LTDC + DMA2D

開發板 正點原子STM32H743 阿波羅固件包 STM32Cube MCU Package for STM32H7 1.12.1開發工具 STM32CubeMX STM32CubeIDE根據原理圖適配所有GPIO&#xff0c;并設置所有GPIO速度 Very Hight

北京JAVA基礎面試30天打卡10

1.最佳左前綴原則是什么 Q:什么是MySQL索引I的最左匹配原則&#xff1f; A:最左匹配原則是指&#xff0c;在復合索引引中&#xff0c;查詢條件需要按照索引列的順序從最左側列開始依次匹配。只有查詢條件中的列按照索引的最左邊列開始進行匹配,索引引才能被有效使用。 Q:能否舉…

五、ZooKeeper、Kafka、Hadoop、HBase、Spark、Flink集群化軟件的部署

五、ZooKeeper、Kafka、Hadoop、HBase、Spark、Flink集群化軟件的部署 文章目錄五、ZooKeeper、Kafka、Hadoop、HBase、Spark、Flink集群化軟件的部署1.作用主要作用&#xff08;通俗說法&#xff09;對實戰項目有什么用&#xff1f;&#xff08;直接舉例&#xff09;2.集群化軟…

下載及交叉編譯glib,記錄

下載及交叉編譯glib&#xff0c;記錄 編譯參見這篇博客 嵌入式arm交叉編譯移植bluez5.0最新教程_bluez移植-CSDN博客 編譯命令有更新&#xff1a; make -j4 CFLAGS"-Wno-format-overflow" glib庫的作用&#xff1a; glib 是 GNOME 項目下的一個基礎庫&#xff0c…

從 0 到 1 玩轉Claude code(藍耘UI界面版本):AI 編程助手的服務器部署與實戰指南

前言 藍耘 Coding UI 作為基于 Claude Code 的可視化工具&#xff0c;憑借對本地項目的深度掌控、與 Git 倉庫的無縫銜接以及直觀的交互界面&#xff0c;正在重構開發者的工作流。本文將帶你一步步完成從環境搭建到實戰使用的全流程&#xff0c;讓這款工具真正成為你的編程「副…

docker使用指定的MAC地址啟動podman使用指定的MAC地址啟動

docker指定固定的mac地址 1】創建自定義橋接網絡并配置 MAC 地址保留 docker network create --driver bridge custom_bridge2】啟動容器并指定使用自定義網絡 docker run -it --name your-container --network custom_bridge --mac-address 02:42:ac:11:00:02 your-image--mac…

抽獎程序web程序

使用html實現抽獎程序&#xff0c;沒有后臺&#xff0c;如果需要后續寫個后臺可以配置&#xff0c;沒有過多的介紹&#xff0c;看代碼吧 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><title>婚禮抽獎</…

【Python辦公】Excel轉json(極速版)-可自定義累加字段(如有重復KEY)

目錄 專欄導讀 ?? 亮點特性 ?? 安裝與運行 ??? 界面與區域說明 ?? 使用示例 ?? 使用建議 ? 常見問題(FAQ) ?? 技術要點 完整代碼 ?? 結語 專欄導讀 ?? 歡迎來到Python辦公自動化專欄—Python處理辦公問題,解放您的雙手 ?????? 博客主頁:請點擊——…

JavaScript 防抖(Debounce)與節流(Throttle)

在 JavaScript 前端開發中&#xff0c;處理高頻率事件&#xff08;如窗口調整、輸入框輸入、頁面滾動&#xff09;時&#xff0c;如果不加以控制&#xff0c;會導致性能問題&#xff0c;如頁面卡頓或資源浪費。防抖&#xff08;Debounce&#xff09;和節流&#xff08;Throttle…

探索無人機圖傳技術:創新視野與無限可能

近年來&#xff0c;無人機技術的飛速發展不僅改變了航空行業的格局&#xff0c;還深刻影響了多個領域的日常運作。無人機圖傳技術作為無人機的核心技術之一&#xff0c;憑借其精準的圖像傳輸能力和高效的遠程操作特性&#xff0c;正在成為各行各業的得力助手。從空中拍攝到實時…

Comfyui進入python虛擬環境

如果你的 Python 可執行文件&#xff08;python.exe&#xff09;位于 C:\comfyui\.venv\Scripts&#xff0c;那么 .venv 本身已經是一個虛擬環境&#xff0c;你只需要 激活它&#xff0c;而無需再創建一個新的虛擬環境。如何激活這個已有的虛擬環境&#xff1f; 1. 打開終端&am…

秋招春招實習百度筆試百度管培生筆試題庫百度非技術崗筆試|筆試解析和攻略|題庫分享

筆試介紹 百度非技術崗筆試采用的是規定時間統一筆試形式&#xff0c;管培生會有兩場考試分別是7月底和8月中旬&#xff0c;其他非技術類崗位一般在8月中旬開始。 行測題必考&#xff0c;有些崗位考簡答題&#xff0c;比如管培生以及產品經理等崗位。 筆試內容 筆試內容一…

低資源語言翻譯:數據增強與跨語言遷移學習策略

文章目錄一、低資源語言翻譯的挑戰1.1 數據稀缺性1.2 語言特性復雜1.3 評估困難二、數據增強策略&#xff08;Data Augmentation&#xff09;2.1 基于單語數據的增強2.2 基于平行數據的增強2.3 多模態數據增強三、跨語言遷移學習策略&#xff08;Cross-Lingual Transfer Learni…

【每天一個知識點】時間序列聚類

一、什么是時間序列聚類&#xff1f;如果把數據比作一本書&#xff0c;那么時間序列&#xff08;Time Series&#xff09;就是一本按時間順序記錄事件的日記。它可能是股票每天的價格波動、某臺機器的溫度曲線、一個城市的空氣質量變化&#xff0c;甚至是人的心電信號。時間序列…

對抗損失(GAN)【生成器+判斷器】

這個是啥呢&#xff0c;搞圖片生成用的。我搜了下&#xff0c;把整體流程記錄下&#xff0c;過程中會用到GAN準備數據集&#xff08;真實圖像素材&#xff09; 目標生成人臉的&#xff0c;你像游戲注冊時選一個臉。捏臉。那么準備真實人臉圖片老規矩&#xff0c;縮放裁剪…

5分鐘入門C++

這是5分鐘入門 C 的精簡 Demo&#xff0c;盡量涵蓋核心概念&#xff1a;變量、函數、類、控制流、STL 容器&#xff0c;讓你快速理解 C 的基本用法。#include <iostream> // 輸入輸出 #include <vector> // 動態數組 #include <algorithm> // 常用算法…