You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# TCP数据包丢失问题:大字符串传输仅接收1400字节求助

解决TCP大字符串传输截断问题

这个问题我太熟了——你碰到的是TCP流式传输的典型坑!

问题根源

TCP是面向流的传输协议,不是像UDP那样的“数据包”协议。你调用NetworkStream.Read()时,它只会返回当前网络缓冲区里已经收到的字节数,而不是你发送的全部数据。1400字节左右刚好是大多数网络的MTU(最大传输单元)大小,所以大内容会被拆分成多个TCP分段发送,你的单次Read()只能拿到第一个分段的数据,剩下的就被留在缓冲区里没被读取(不是真的丢了)。

解决方案:确保读取完整数据

最可靠的解决方式是先发送数据的长度,再发送实际内容,让接收端明确知道要读取多少字节,然后循环读取直到拿到全部数据。

修改后的客户端代码

发送数据(新增长度前置逻辑)

public static string Senddata(string BarcodeText) {
 try {
 string textToSend = BarcodeText.ToString();
 byte[] bytesToSend = ASCIIEncoding.ASCII.GetBytes(textToSend);
 // 先发送数据长度(用4字节int表示,让接收端知道要读多少)
 byte[] lengthBytes = BitConverter.GetBytes(bytesToSend.Length);
 nwStream.Write(lengthBytes, 0, lengthBytes.Length);
 // 再发送实际内容
 nwStream.Write(bytesToSend, 0, bytesToSend.Length);
 return "Success";//if sent
 } catch (Exception) {
 return "Fail";//if not sent
 }
}

接收数据(改成循环读取完整内容)

public static string Getdata() {
 try {
 // 第一步:读取数据长度(固定4字节)
 byte[] lengthBuffer = new byte[4];
 int bytesRead = nwStream.Read(lengthBuffer, 0, 4);
 if (bytesRead != 4) {
     return "Failed to read data length";
 }
 int dataLength = BitConverter.ToInt32(lengthBuffer, 0);

 // 第二步:循环读取所有数据,直到凑够指定长度
 byte[] dataBuffer = new byte[dataLength];
 int totalBytesRead = 0;
 while (totalBytesRead < dataLength) {
     int read = nwStream.Read(dataBuffer, totalBytesRead, dataLength - totalBytesRead);
     if (read == 0) {
         // 连接意外断开
         return "Connection closed prematurely";
     }
     totalBytesRead += read;
 }

 str = Encoding.GetEncoding("ISO-8859-1").GetString(dataBuffer, 0, totalBytesRead);
 return str;
 } catch (Exception ex) {
 return $"Error receiving data: {ex.Message}";
 }
}

修改后的服务器端代码

接收数据(新增循环读取逻辑)

public static string GetDatafromClient() {
 try {
 nwStream = client.GetStream();
 // 第一步:读取数据长度
 byte[] lengthBuffer = new byte[4];
 int bytesRead = nwStream.Read(lengthBuffer, 0, 4);
 if (bytesRead != 4) {
     return "-";
 }
 int dataLength = BitConverter.ToInt32(lengthBuffer, 0);

 // 第二步:循环读取完整数据
 byte[] buffer = new byte[dataLength];
 int totalBytesRead = 0;
 while (totalBytesRead < dataLength) {
     int read = nwStream.Read(buffer, totalBytesRead, dataLength - totalBytesRead);
     if (read == 0) {
         return "-";
     }
     totalBytesRead += read;
 }

 return Encoding.ASCII.GetString(buffer, 0, totalBytesRead);
 } catch (Exception) {
 return "-";
 }
}

发送数据(新增长度前置逻辑)

public static void SendDatatoClient(string DataToSend) {
 FileHandling.SaveToFile(DataToSend);
 byte[] bytesTosend = Encoding.GetEncoding("ISO-8859-1").GetBytes(DataToSend);
 // 先发送数据长度
 byte[] lengthBytes = BitConverter.GetBytes(bytesTosend.Length);
 nwStream.Write(lengthBytes, 0, lengthBytes.Length);
 // 再发送实际内容
 nwStream.Write(bytesTosend, 0, bytesTosend.Length);
}

额外注意事项

  • 编码一致性:你客户端发送用ASCIIEncoding.ASCII,接收却用ISO-8859-1,服务器端刚好反过来,这可能导致乱码,建议统一编码(比如都用UTF-8或者ISO-8859-1)。
  • 字节序问题:如果客户端和服务器端运行在不同架构的机器上(比如x86和ARM),BitConverter的字节序可能不兼容,这种情况下可以手动指定大端/小端序来处理。

内容的提问来源于stack exchange,提问作者user8511293

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:58:04