Skip to content

bug: [P1] 非法长度头后的完整帧被挂起,必须等额外字节到达才交付 #64

Description

@CSJ608

评审基线:StreamFrame 2.6.0,提交 4b892d9eaa11cf003b5d10793e735b0604bc17ed(2026-09-08 仓库评审)。

问题与影响

P1,已独立复现。 同一批输入含“坏长度头 + 合法完整帧”时,坏头被丢弃,但后续完整帧不立即交付。请求—响应协议中,对端等待应答、不再发字节,可导致双方一直等待。

位置:src/StreamFrame/Framing/LengthPrefixFramer.cs:77;
src/StreamFrame/Connection/FrameDecoder.cs:95;
src/StreamFrame/Connection/FrameDecoder.cs:144。

原因链:非法长度分支消费四字节后返回 false → Decoder 的 while 循环结束 → AdvanceTo(buffer.Start, buffer.End) 将剩余完整帧标记为已检查 → 等待更多网络输入。这里混淆了“已有消费进展,可继续解析”和“必须等更多字节”。

最小报文与实测

Windows、.NET 8.0.30,默认 LengthPrefixFramer,普通 byte[]/string Codec:

FF FF FF FF  00 00 00 03  41 41 41
^^^^^^^^^^  ^^^^^^^^^^^  ^^^^^^^^
非法长度头   合法长度=3    payload=AAA
  1. 本地 TcpClient 连接被动 StreamConnection,启动 GetMessages 消费。
  2. 一次 WriteAsync 写入以上完整报文。
  3. 等 FrameError 确认坏头已被处理,500ms 后消息任务仍未完成。
  4. 再发送单字节 00,之前的 AAA 立即交付。

实测输出:

message completed after invalid header + valid frame = False
after extra byte delivered=3

建议与验收

  • 明确 Framer false 返回值与缓冲推进契约;发生消费进展时能继续处理现有缓冲,且无进展时不会忙循环。
  • 坏头 + 合法完整帧在没有后续写入的情况下立即交付。
  • 覆盖连续多个坏头、合法半帧、粘包、EOF,以及自定义 Framer false 但推进缓冲的情形。
  • 开启 IncompleteFrameTimeout 时,不把已经完整缓冲的消息误当半帧超时。
  • FrameError 丢弃字节、SessionId 和快照元数据保持正确。
  • 保留当前明确的重同步策略,若要改变非法长度为断连策略需单独说明兼容影响。

实施按 AGENTS.md:从最新 main 建分支、同步 CHANGELOG Unreleased、通过 Release build/test、走 PR;本 Issue 仅登记工作,不代表已实施修复。

Activity

  1. CSJ608 commented on Sep 8, 2026

    @CSJ608
    OwnerAuthor

    已通过 PR #74 修复并 rebase 合并为 cadbfd6。保留非法长度头四字节丢弃策略与公共签名,false 且消费有进展时继续解码,无进展等待输入。

    验收证据:原实现 6 个确定性 Pipe 用例全红,修复后新增共 7 项通过;覆盖无后续写入交付、连续坏头、粘包、半帧续写/EOF、自定义 Framer 推进与无进展停止、完整缓冲不触发半帧超时、丢弃字节/SessionId/快照元数据。既有超时与快照截断回归通过。

    本地 Release build 零警告错误;完整测试三框架各 115/115(首次 net8.0 三项既有 TCP 测试瞬态失败,原命令重跑一次全绿,未改断言)。PR CI 与 CodeQL 全绿。正在核验合并后 main CI。

  2. CSJ608 commented on Sep 8, 2026

    @CSJ608
    OwnerAuthor

    合并后验证完成:main CI(Ubuntu net8.0/net10.0、Windows net48、AOT)与 CodeQL 全绿。

    实施分支已删除,#64 验收完成。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions