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

C# 如何构建MemoryStream数据包并从NetworkStream提取相关数据

方案说明

你当前写的WriteCanvasStrokes和ReadCanvasStrokes核心逻辑已经匹配字符串报文的「1字节操作码 + 4字节内容长度 + N字节内容」结构,完全符合需求,只需要修正两个边缘问题即可稳定运行:

问题1:MemoryStream获取有效字节的错误修正

你现有SendCanvasStrokesToServer方法里调用memoryStream.GetBuffer()是错误的,该方法返回的是内存流预分配的完整底层数组,包含未写入的空白字节,会导致多余无效数据被发送。修改为memoryStream.ToArray()即可获取实际写入的有效字节。
修改后代码:

public void SendCanvasStrokesToServer(MemoryStream memoryStream)
{
    var strokesPacket = new PacketBuilder();
    strokesPacket.WriteOpCode(7);
    // 替换GetBuffer为ToArray获取实际有效字节
    strokesPacket.WriteCanvasStrokes(memoryStream.ToArray());
    _client.Client.Send(strokesPacket.GetPacketBytes());
}

问题2:接收端读满指定长度的逻辑修正

NetworkStream的Read方法不保证一次就能返回你请求的length长度的字节,尤其是在网络延迟、报文较大的场景下,会出现只读取到部分数据的情况,需要循环读取直到收满指定长度的字节。修改ReadCanvasStrokes方法如下:

public byte[] ReadCanvasStrokes()
{
    var length = ReadInt32();
    byte[] strokesBuffer = new byte[length];
    int totalRead = 0;
    while (totalRead < length)
    {
        int read = _ns.Read(strokesBuffer, totalRead, length - totalRead);
        // read返回0说明连接已断开,可根据业务需求调整异常处理逻辑
        if (read == 0)
        {
            throw new IOException("连接已断开,无法读取完整报文");
        }
        totalRead += read;
    }
    return strokesBuffer;
}

补充提示:你现有的ReadMessage方法也存在同样的读取不完整问题,建议用相同的循环读取逻辑修改,避免字符串接收异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:24:09