我正在编写运行以下协议的erlang tcp-server。
<<?SPECIAL_BYTE, 0, PayloadLength:2/big-unsigned-integer-unit:8>>
。此数据包表明该服务器必须读取下一个PayloadLength
字节的原始数据。当然,我可以接收原始数据流并在erlang代码中解析此协议。但我想知道,有没有办法使用内置的erlang数据包打包?当我的数据包前面有它的长度时,我可以说[{packet,HeaderLength}]。有没有办法强制erlang自动打包4字节chuks接收数据?
UPD:我打算使用{active,once}模式。另外我可以使用gen_tcp:recv(Socket,4),但是我担心在这种情况下由于多个套接字读取会导致性能下降。我的恐惧是否合理?
答案 0 :(得分:1)
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?但是,我强烈建议在尝试优化之前专注于获得有效的实施。过早优化永远不会产生良好的结果。