如何正确序列化网络数据包

网络工程 tcp 网络 联网 传输协议 序列化
2022-02-25 11:07:03

所以我目前正在编写一个基本上只是一个服务器和一个客户端的程序。这个想法是我希望他们能够通过来回发送数据包来与一个和另一个通信。我正试图弄清楚如何正确处理这个问题。这是我目前的事情流程。

  1. 我启动服务器并等待传入​​连接。
  2. 客户端连接到服务器并发送一个看起来像这样(0x1)的数据包,这是指示操作码的第一个也是唯一一个字节。我想用这个数据包发送更多数据,这就是“问题”发生的地方。我不确定如何序列化数据包。

我要发送的数据是一个字符串,可以是 2、50 个字符,后跟一个 ip 地址和几个长度为 10 到 20 个字符的字符串(大约 2 个)。

现在,我是否可以从创建一个字节数组开始,附加第一个字节(操作码),后跟不是固定大小字符串的字符串。这将很难反序列化。我是否在该字符串的字节之前包含所述字符串的长度?

1个回答

您应该设计您的第一个有线协议,并在每个数据字段之前添加一个标头,例如[ Length, Type, Value ]. 一个通用的标头将使序列化和调试变得容易。

请务必考虑您是否希望您的协议在流通道上工作,例如 TCP 连接;或数据包/数据报通道,如 UDP,以及。这可能会影响您在传输时是否需要对整个消息/操作的长度进行编码(TCP),或者可以简单地推断该长度是接收到的数据报的总长度(UDP)。


在设计自己的协议之前,了解一些现有协议(可能是您熟悉使用的协议(但不是对其实现进行编程))是一个好主意,以便在设计自己的协议之前建立概念基础。 正如他们所说,在跑步之前先走。

在我职业生涯的早期,BGP 对我来说是一个很好的例子,因为我都在实践中使用它,并且想了解更多关于实现序列化器/反序列化器代码的信息。

我建议您查看各种 BGP 消息和属性格式。它们从RFC4271 §4开始记录。

我建议以 BGP 为例的原因是 BGP 使用几种不同的技术来编码数据。它是经过多年开发的,随着时间的推移,设计的重点发生了一点变化,从紧凑性转向易于实现和可扩展性。

例如,某些字段具有固定长度,永远不会直接编码到 BGP 消息中。其他人则灵活并写下他们的长度。

此外,一些字段包含为不同类型的属性重复使用公共标志的标题。这是一个使实现更容易和更明显的特性。路径属性是一个很好的例子(尽管它们首先被记录为携带它们的UPDATE 消息的一部分。)

此外,BGP 的可扩展性如此之强,以至于 BGP 路由器的全球网络不必都支持其所有功能,这些功能才能正常工作。路由器未知的 BGP 属性仍然可以通过它传递到相邻路由器,同时遵循各种规则。

最后,由于 BGP 是一个如此古老的协议,它已经通过新功能进行了多次扩展,您可以看到其工作原理的实际示例。一个很好的例子是BGP 扩展社区


希望这可以帮助!