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

TCP消息帧实现异常:仅读取前4个字符求助

问题排查与修复

你的接收端核心错误是把读取长度前缀时的实际读取字节数当成了消息内容的长度,而非将读取到的4字节数据解析为真正的消息长度。

具体错误分析

在ReceiveAsync方法中:

var messageLength = await _client.GetStream().ReadAsync(messageLengthByte, 0, messageLengthByte.Length);

这里的messageLength是ReadAsync返回的实际读取字节数(因为你要读取4字节的int,所以这个值固定为4),但你直接用这个值作为消息内容的长度,导致后续只读取了4字节的消息内容,所以输出只有{"Cl这4个字符。

修复后的接收端代码

修改ReceiveAsync方法,正确解析长度前缀:

public async Task ReceiveAsync()
{
    var messageLengthByte = new byte[sizeof(int)];
    var bytesReadForLength = await _client.GetStream().ReadAsync(messageLengthByte, 0, messageLengthByte.Length);

    if (bytesReadForLength == 0)
    {
        return;
    }
    
    // 将读取到的4字节解析为真正的消息内容长度
    var messageLength = BitConverter.ToInt32(messageLengthByte, 0);
    Console.WriteLine($"Message Length: {messageLength}");

    var buffer = new byte[messageLength];
    var totalBytesRead = 0;

    while (totalBytesRead < messageLength)
    {
        totalBytesRead += await _client.GetStream().ReadAsync(buffer, totalBytesRead, messageLength - totalBytesRead);
    }
    
    Console.WriteLine($"Message: {Encoding.Default.GetString(buffer)}");
    
    OnReceived(buffer);
}

额外注意事项

  • 字节序一致性:如果发送端和接收端运行在不同字节序的平台(比如Windows是小端,部分嵌入式设备是大端),需要统一字节序。可以在发送端将长度转换为网络字节序(大端),接收端再转换回来:
    • 发送端修改:var lengthPrefix = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(message.Length));
    • 接收端修改:var messageLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(messageLengthByte, 0));
  • 确保完整读取长度前缀:当前代码假设一次能读满4字节,实际生产环境中可以加循环确保读够4字节,避免因为TCP粘包/拆包导致的部分读取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 07:08:31