gpt4 book ai didi

python - 通过TCP在python中接收分隔的Protobuf消息

转载 作者:太空宇宙 更新时间:2023-11-03 15:15:53 24 4
gpt4 key购买 nike

我正在尝试接收一条 protobuf 消息,该消息是从我的 python 应用程序中使用“writeDemitedTo()”的 java 应用程序发送的。

经过一些研究,我已经发现了这段代码来从套接字读取消息,对其进行解码并解析。

data = sock.recv()
(size, position) = decoder._DecodeVarint(data, 0)
msg = MessageWrapper_pb2.WrapperMessage().ParseFromString(data[position:position + size])

我现在得到的是 google.protobuf.message.DecodeError: Truncated message Exception。

有人遇到过类似的问题或者知道如何从套接字读取分隔数据并正确解析它吗?

编辑:

这是对我有用的解决方案。

def read_java_varint_delimited_stream(sock):
buf = []
data = sock.recv()
rCount = len(data)
(size, position) = decoder._DecodeVarint(data, 0)

buf.append(data)
while rCount < size+position:
data = sock.recv(size+position-rCount)
rCount += len(data)
buf.append(data)

return b''.join(buf), size, position

def readMessage(sock):
data, size, position = read_java_varint_delimited_stream(sock)
msg = MessageWrapper_pb2.WrapperMessage()
msg.ParseFromString(data[position:position + size])

return msg

最佳答案

TCP 是一种流协议(protocol),没有任何内容表明一端的 recv 与另一端的单个 send 配对。基于消息的协议(protocol)需要某种方式来标记其边界,以便接收者知道如何找到消息边界。

writeDelimitedTo docs假设先发送 varint 大小,然后发送数据。因此,读取 varint,然后读取该字节数。

深入挖掘,varint docs描述如何使用字节的高位来标记连续性来对其值进行编码。我们可以编写自己的解码器

import struct

def read_java_varint_delimited_stream(sock):
sz = 0
while True:
vbyte, = struct.unpack('b', sock.recv(1))
sz = (vbyte << 7) + (vbyte & 0x7f)
if not vbyte & 0x80:
break
data = []
while sz:
buf = sock.recv(sz)
if not buf:
raise ValueError("Buffer receive truncated")
data.append(buf)
sz -= len(buf)
return b''.join(buf)

关于python - 通过TCP在python中接收分隔的Protobuf消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43897955/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com