parsing - 作为读取消息的服务器,您如何找出消息的长度?

标签 parsing go tcp network-protocols

我正在编写一个服务器,它接受来自客户端的传入连接,然后从中读取(通过 net.Conn.Read())。很明显,我要把消息读入一个 []byte slice ,然后以不相关的方式处理它,但问题是——我如何首先找出这条消息的长度来创建一个相应长度的 slice ?

最佳答案

这完全取决于您尝试从连接中读取的协议(protocol)的设计。

如果您正在设计自己的协议(protocol),则需要为您的读者设计某种方式来确定何时停止阅读或预先声明消息的长度。

对于二进制协议(protocol),您经常会发现某种固定大小的 header ,其中包含某个已知的length 值(例如,big-endian int64)/可发现的 header 偏移量。然后,您可以解析 length 偏移量处的值,并在到达可变长度数据开始的偏移量后使用该值读取正确数量的数据。二进制协议(protocol)的一些示例包括 DNSHTTP/2

对于文本协议(protocol),何时停止阅读将编码在解析规则中。文本协议(protocol)的一些示例包括 HTTP/1.xSMTP。例如,HTTP/1.1 请求声明协议(protocol)如下所示:

METHOD /path HTTP/1.1\r\n
Header-1: value\r\n
Header-2: value\r\n
Content-Length: 20\r\n
\r\n
This is the content.

第一行(表示以 \r\n 结尾的行)必须包含 HTTP 方法,后跟路径(可以是绝对路径或相对路径),然后是版本。

后续行被定义为标题,由一个键和一个值组成。

键包括从行首到冒号的任何文本,但不包括冒号。冒号后是可变数量的无关紧要的空格字符,后跟值。

其中一个 header 很特殊,表示即将到来的正文的长度:Content-Length。此 header 的值包含要作为主体读取的字节数。对于我们的简单情况(忽略尾部、分块编码等),我们假设正文的结尾表示请求的结尾,另一个请求可能紧随其后。

在最后一个 header 之后是一个空行,表示 header block 的结尾和正文的开头 (\r\n\r\n)。

一旦您完成读取所有 header ,您将从您解析的 Content-Length header 中获取值,并读取与其值对应的下一个字节数。

有关更多信息,请查看:

关于parsing - 作为读取消息的服务器,您如何找出消息的长度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38173153/

相关文章:

arrays - 如何在 flutter 中解析json?

C++ - 搜索带下划线的字符串时,行解析器停止

go - 等待 gin HTTP 服务器启动

go - 如何访问所有连接的 tcp 客户端的变量?

c# - 如何编写可扩展的基于 TCP/IP 的服务器

javascript - 切换网站语言 JS/JSON

python - 在 python 中使用 cElementTree 解析 XML

csv - 大型 CSV Go channel 内存过多

go - 生成后的模板标识

c# - 如何使TCP套接字保持事件状态并检测断开连接?