首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Socket 網路程式設計學習筆記 (4):TCP 訊息邊界處理三大策略

     編輯:關於.NET

問題背景

TCP 是位元組串流協定,無訊息邊界。連續發送 "msg1"、"msg2",接收端可能收到 "msg1msg2" 或 "msg1ms" + "g2"。同機測試常正常,跨機器必現問題。

三大解決策略

策略 1:固定長度訊息

  • 協定規定所有訊息固定長度 (如 1024 bytes)
  • 發送端不足補位,接收端定長讀取
  • 缺點:短訊息浪費頻寬,長訊息需分片

策略 2:長度前綴 (推薦)

  • 發送前先傳 4 位元組整數表示訊息長度
  • 接收端先讀 4 bytes 取得長度,再循環讀取完整資料
  • 優點:可變長度、無浪費、解析簡單
  • 下一篇結合實體物件傳輸詳細實作

策略 3:分隔符 (適用文字協定)

  • 用特定字元 (如換行符 \n) 標記訊息結束
  • 接收端逐字元檢查分隔符
  • 缺點:大訊息效能差、訊息內容不可含分隔符
  • .NET 提供 StreamReader.ReadLine() / StreamWriter.WriteLine() 簡化實作

StreamReader/Writer 實作範例

NetworkStream ns = tcpClient.GetStream();
StreamReader reader = new StreamReader(ns);
StreamWriter writer = new StreamWriter(ns) { AutoFlush = true };

// 發送
writer.WriteLine("Welcome to server");  // 自動加 \n

// 接收
string msg = reader.ReadLine();         // 讀到 \n 為止

兩大陷阱

  1. 成對使用:WriteLine/ReadLine 必須配對,否則 ReadLine 永遠阻塞等待換行符
  2. 內容禁含換行:訊息本身若含 \n 會被誤判為結束,導致資料截斷

NetworkStream 直接讀寫

// 發送
byte[] data = Encoding.ASCII.GetBytes("message");
ns.Write(data, 0, data.Length);

// 接收 (需自行處理邊界)
byte[] buffer = new byte[1024];
int read = ns.Read(buffer, 0, buffer.Length);
string msg = Encoding.ASCII.GetString(buffer, 0, read);

策略選擇建議

下一篇預告

結合「長度前綴」策略,實作實體物件序列化傳輸 (SOAP/Binary/Xml)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
場景推薦策略
高效能二進位協定、已知最大長度固定長度
一般雙向通訊、可變長度資料長度前綴
簡單文字指令協定 (如 SMTP、HTTP Header)分隔符 (CRLF)
現有協定規定特定分隔符分隔符