我正在使用Python中的基本网络协议,它应该能够传输两个ASCII字符串(读取:EOL终止)和二进制数据。 对于后者是可能的,我选择创建语法,使其包含将成为二进制的字节数。
对于SimpleParse,语法到目前为止看起来像这样[1]:
EOL := [\n]
IDENTIFIER := [a-zA-Z0-9_-]+
SIZE_INTEGER := [1-9]*[0-9]+
ASCII_VALUE := [^\n\0]+, EOL
BINARY_VALUE := .*+
value := (ASCII_VALUE/BINARY_VALUE)
eol_attribute := IDENTIFIER, ':', value
binary_attribute := IDENTIFIER, [\t], SIZE_INTEGER, ':', value
attributes := (eol_attribute/binary_attribute)+
command := IDENTIFIER, EOL
command := IDENTIFIER, '{', attributes, '}'
问题是我不知道如何指示SimpleParse以下将成为SIZE_INTEGER字节在运行时的二进制数据。
原因是终端BINARY_VALUE的定义满足了我现在的需求,因此无法更改。
由于
修改
我想解决方案是告诉它在与生产binary_attribute匹配时停止并让我手动填充AST节点(通过socket.recv()),但是怎么做? < / p>
修改2
Base64编码或类似功能不是一种选择。
[1]我没有测试过,所以我不知道它是否真的有用,只是为了让你有所了解
答案 0 :(得分:4)
如果语法和你引用的语法一样简单,那么使用解析器生成器可能有点过分了吗?您可能会发现手动滚动自己的递归解析器更简单,更快捷。
答案 1 :(得分:1)
如果您希望您的应用程序具有可移植性和可靠性,我建议您只通过线路传递标准ASCII字符。
不同的计算机体系结构具有不同的二进制表示,不同的字大小,不同的字符集。有三种方法可以解决这个问题。
首先,您可以忽略这些问题,并希望您只需在单个平台上实施协议。
两个你可以使用所有计算机技术,并为每种可能的数据类型ala CORBA提供“基数形式”。
通过网络发送数据时,您可以实用并使用“sprintf”和“scanf”的魔力将数据转换为纯ASCII字符。
我还建议您的协议包含消息开头或接近消息的消息长度。自制协议中最常见的错误是接收伙伴期望的数据多于发送的数据,并且永远等待从未发送过的数据。
答案 2 :(得分:0)
我强烈建议您考虑使用construct库来解析二进制数据。它还支持文本(ASCII),因此当它检测到文本时,您可以将其传递给基于SimpleParse的解析器,但二进制数据将使用构造进行解析。它非常方便和强大。