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

.NET 8中MS Quic客户端接收数据偶尔损坏的问题与解决

.NET 8 MS Quic流传输数据损坏问题的解决方案

问题场景

在本地WiFi网络中使用.NET 8的MS Quic实现服务器到客户端的数据流传输时,客户端接收的部分流数据损坏,仅约60%的流能完整正确接收。传输的流为约15KB的byte[],结构如下:

  • 前50字节:写入时间戳
  • 中间50字节:包计数器ID
  • 剩余约15KB:PNG文件字节数据

测试中调整了不同传输频率(如每2秒传输一次),排除了带宽和硬件故障的可能性,损坏流仅约5%的字节出现错误。

根因分析

问题核心是客户端读取流时未校验读取数据的长度:单次调用ReadAsync无法保证一次性返回全部预期数据,原代码直接使用单次读取的结果进行业务处理,导致不完整的字节数组被解析,最终引发数据损坏。

修复后的关键读取代码

通过循环调用ReadAsync,直到读取到预期的完整数据长度,解决了数据不完整的问题:

public async Task ReceiveStreamAndSendFeedback()
{
    int msgCounter = 0;
    int receiveArrayLength = 50 + 50 + 15284;

    try
    {
        if (null == _incomingStream)
        {
            _incomingStream = await _connection.AcceptInboundStreamAsync();
        }
        if (null == _outgoingStream)
        {
            _outgoingStream = await _connection.OpenOutboundStreamAsync(QuicStreamType.Bidirectional);
        }
        bool isRunning = true;
        bool isStreamStartAnnounced = false;

        while (isRunning)
        {
            byte[] buffer = new byte[receiveArrayLength];
            int streamLength = 0;
            // 循环读取直到获取完整的预期数据长度
            while (streamLength < receiveArrayLength)
            {
                streamLength += await _incomingStream.ReadAsync(buffer, streamLength, receiveArrayLength - streamLength);
            }
            // 原错误实现:仅单次读取,未校验长度
            // streamLength = await _incomingStream.ReadAsync(buffer, 0, receiveArrayLength);
            // 后续业务逻辑处理
        }
    }
    // 异常处理代码
}

完整代码示例

服务器入口代码

QuicServerPrototype quicServerPrototype = new QuicServerPrototype();

await quicServerPrototype.Initi();
List<Task> tasks = new List<Task>();

tasks.Add(quicServerPrototype.SendStream());
tasks.Add(quicServerPrototype.ReceiveFeedback());

// 并行启动所有任务
await Task.WhenAll(tasks);

QuicServerPrototype.cs包含初始化、流发送、反馈接收的完整逻辑

客户端入口代码

QuicClientPrototype quickClientPrototype = new QuicClientPrototype();

try
{
    await Task.Delay(4000);

    await quickClientPrototype.Initi();

    await quickClientPrototype.ReceiveStreamAndSendFeedback();
}
catch (Exception e)
{
    throw new Exception(e.Message,e);
}

QuicClientPrototype.cs包含初始化、流接收及反馈发送的完整逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 08:52:32