串口读到的是字节流,不是消息。设备分几次发、中间夹杂噪声、响应迟到时怎么保证协议可靠?这篇用一个 pty 伪终端模拟的「设备」配合 jSerialComm,真实运行帧的累积、CRC 重同步、读超时模式与带序号的重试。
设备把一个 45 字节的帧分 4 次发出(每次间隔约 30 ms):每次 readBytes 返回的字节数 = [12, 12, 12, 9],分别在 [0, 39, 79, 119] ms 返回;总共 45 字节 按帧解析:读到完整帧 1 个,payload 长度 40,第一次读到的 12 字节不足以构成一个帧(帧头 + 长度字段 + 数据 + CRC 共 45 字节)
设备依次发出:7 字节垃圾 + 一个 CRC 错误的帧 + 一个正确的帧(seq=1)+ 3 字节垃圾 + 一个正确的帧(seq=2),共读到 43 字节 解析结果:接受 2 个帧 seq=[1, 2],payload [first, second];丢弃的垃圾字节数 21;CRC 不符而重新找帧头的次数 1
TIMEOUT_NONBLOCKING 设备不发任何数据时 readBytes(8) → 返回 0,耗时 0 ms TIMEOUT_READ_SEMI_BLOCKING(300 ms) 设备不发任何数据时 readBytes(8) → 返回 0,耗时 302 ms TIMEOUT_READ_BLOCKING(300 ms) 设备不发任何数据时 readBytes(8) → 返回 0,耗时 301 ms TIMEOUT_READ_BLOCKING(2000 ms):设备 100 ms 后只发来 3 字节(要求读 8 个):readBytes → 3,耗时 2102 ms(要读满 8 个字节或超时) TIMEOUT_READ_SEMI_BLOCKING(2000 ms):同样的 3 字节 → readBytes → 3,耗时 103 ms(有数据就返回) bytesAvailable() = 0
t=0ms 发出请求 seq=1 t=209ms seq=1 超过 200 ms 没有响应,重试 t=212ms 发出请求 seq=2 t=213ms 收到 seq=1 的响应「late-reply-for-seq1」→ 不是当前请求(seq=2),丢弃 t=244ms 收到 seq=2 的响应「reply-for-seq2」→ 接受 结果:reply-for-seq2;总耗时 250 ms