Erlang如何接收TCP数据包

3

我正在编写一款Erlang TCP服务器,运行以下协议。

  1. 每个数据包大小恰好为4字节。
  2. 有一个特殊情况的数据包 - <<?SPECIAL_BYTE, 0, PayloadLength:2/big-unsigned-integer-unit:8>>。此数据包表示服务器必须读取下一个PayloadLength字节的原始数据。

我可以接收原始数据流并在Erlang代码中解析此协议。但是我想知道是否有任何方法可以使用内置的Erlang数据包封装?当我的数据包以其长度为前缀时,我可以使用[{packet,HeaderLength}]。是否有任何方法可以强制Erlang自动将接收到的数据打包成4字节的块呢?

更新:我计划使用{active,once}模式。我也可以使用gen_tcp:recv(Socket,4),但我担心在这种情况下由于多次套接字读取而导致性能损失。我的担忧是否有道理?

1个回答

2
Erlang的本地数据包解码非常有用,当它与您的数据实际格式匹配时。如果您的数据包总是使用4字节(32位)大端长度进行编码,那么{packet, 4}正是您所需要的。但是,如果您的编码中存在一些异常情况,则必须使用{packet, raw}并自行解码。
对于解码,您确实可以使用被动模式下的套接字和{active, false},读取四个字节以及其余的数据包内容。您还可以使用主动模式下的套接字,但在这种情况下,您必须准备好接收比数据包头更少或更多的内容,包括超过一个单一数据包的内容。{active, once}可以帮助,但不会解决问题。在您的情况下,被动模式可能更容易处理。
性能方面,您可以参考以下问题:How can the "packet" option of socket in Erlang accelerate the tcp transmission so much?然而,我强烈建议先专注于获取可行的实现,再进行优化。过早优化往往不会产生良好的结果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接