关于本文
本文是通过利用生成式 AI 的自动化生成流程创建的。我们查阅了 RFC 9293 和 .NET Socket API,将向 TCP 字节流附加长度信息的概念整理成了可在 localhost 上进行观察的形式。验证状态:📘 已确认 RFC 及 .NET 官方规范,未在实机上验证
TCP 本身没有应用层的消息边界。因此,我们通过最小的数据来体验在正文前放置“接下来是多少字节”的长度前缀(length prefix)。
首先尝试
$msg='HELLO' $body=[Text.Encoding]::UTF8.GetBytes($msg) $prefix=[BitConverter]::GetBytes([Net.IPAddress]::HostToNetworkOrder($body.Length)) "prefix=$([BitConverter]::ToString($prefix)) body=$msg" $len=[Net.IPAddress]::NetworkToHostOrder([BitConverter]::ToInt32($prefix,0)) "receiver expects $len bytes"
查看此处
接收方在读取正文之前,就能知道5 bytes。Send或Read的关键在于,不是由次数决定,而是由应用程序自身来定义边界。
尝试修改一处
HELLO将こんにちは修改为字节数,并确认作为前缀的是 UTF-8 的字符数而不是字节数。
为什么会这样
TCP 保证的是有序的字节流。固定长度、分隔符、长度前缀等成帧(framing)机制是上层协议的责任。
graph LR L[4-byte length] --> B[payload bytes] B --> R[receiver reads exactly length]
如果在工作中实际使用
在实现中,考虑到前缀本身也可能会被分段接收,必须做到“读取直到凑齐 4 字节”、“读取直到凑齐声明的长度”。同时不无条件分配巨大的声明长度,并设置上限。
RFC 9293: https://www.rfc-editor.org/rfc/rfc9293
Microsoft NetworkStream.Read: https://learn.microsoft.com/dotnet/api/system.net.sockets.networkstream.read
