首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Linux Socket 大數據傳輸接收不全的解決方案

     編輯:程式設計綜合問答

現象

客戶端發送 30KB+ 數據,服務端循環 read() 仍無法一次性讀取完整數據,甚至提前返回 EAGAIN。

根本原因

TCP 是流式協議,無消息邊界。網絡擁塞、滑動窗口、MTU 限制等因素導致數據分片到達,read() 返回已到達的數據,不保證一次讀完應用層預期長度。

解決策略

  1. 發送端確認完整發送:使用循環 send(),檢查返回值累加至總長度。
  2. 應用層協議定長:在數據包頭部添加 4 字節整數標識總長度(網絡序)。
  3. 接收端按長度讀取:
    // 先讀 4 字節包頭
    int totalLen = readN(sockfd, header, 4);
    // 再循環讀取剩餘數據
    char *buf = malloc(totalLen);
    int received = 0;
    while (received < totalLen) {
        int n = read(sockfd, buf + received, totalLen - received);
        if (n < 0) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) continue; // 非阻塞等待
            break; // 錯誤
        }
        received += n;
    }

關鍵點

無論阻塞/非阻塞模式,應用層必須自行實現「收齊指定長度」的邏輯,不可依賴單次 read() 返回預期大小。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved