Erlang二进制协议序列化

4

我目前正在一个大型项目中使用Erlang,但是我对合适的处理方式有疑问。

我通过TCP套接字接收字节。这些字节基于固定协议,发送方是一个Python客户端。Python客户端使用类继承来从对象创建字节。

现在,我希望(在Erlang中)将字节转换为它们对应的消息,它们都有一个共同的消息头。

如何以尽可能通用的方式在Erlang中实现此操作?

此致敬礼,

1个回答

2
使用 Erlang 的二进制语法进行模式匹配和二进制头部消费。但您需要确切地了解所期望接收的字节或位,或是字节或位的字段大小。
例如,假设您期望接收一组字节字符串,其中以 ASCII 字符串“PUSH”或“PULL”开头,后跟您将放置在某处的其他数据。您可以创建一个函数头来匹配这些内容,并捕获其余部分传递给另一个函数,在字节头基础上执行“push()”或“pull()”。
operation_type(<<"PUSH", Rest/binary>>) -> push(Rest);
operation_type(<<"PULL", Rest/binary>>) -> pull(Rest).

第一组字节之后的字节现在将会被存储在 Rest 中,这样你就可以顺序解释随后的任何标题或数据。你也可以匹配整个二进制:

operation_type(Bin = <<"PUSH", _/binary>>) -> push(Bin);
operation_type(Bin = <<"PULL", _/binary>>) -> pull(Bin).

在这种情况下,"_"变量的作用与平常一样 - 你只是检查前导字符,实质上是窥视缓冲区并根据初始内容传递整个内容。你也可以跳过它。假设你知道你将收到一个二进制文件,其中前面有4个字节的填充数据,6个字节的类型数据,然后是其余部分,你想要传递它:
filter_thingy(<<_:4/binary, Type:6/binary, Rest/binary>>) ->
    % Do stuff with Rest based on Type...

很自然地,在函数头中分割二进制数据(无论数据是否等同于字符串),让“Rest”逐步落到适当的函数中。 如果您正在接收Python pickle数据或类似数据,则需要以递归方式编写解析例程,以便每种数据类型的结论都将返回顶部以确定下一个类型,并累积表示迄今读取的数据的树。

上面我只涵盖了8位字节,但还有一种纯位字符串语法,它允许您根据需要轻松地深入比特和字节的细节。 在此处匹配是真正的救星。

希望这篇文章能够增加你的见识而不是让你更加困惑。在通用编程语言中,Erlang中的二进制语法使其成为最令人愉悦的二进制解析环境。

http://www.erlang.org/doc/programming_examples/bit_syntax.html


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