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

通过TCP在python中接收带分隔符的Protobuf消息,python,sockets,protocol-buffers,Python,Sockets,Protocol Buffers,我正在尝试接收protobuf消息,该消息是从python应用程序中带有“writeDelmitedTo()”的java应用程序发送的 经过一些研究,我已经发现了这个代码,可以从套接字读取消息,解码并解析它 data = sock.recv() (size, position) = decoder._DecodeVarint(data, 0) msg = MessageWrapper_pb2.WrapperMessage().ParseFromString(data[position:posit

我正在尝试接收protobuf消息,该消息是从python应用程序中带有“writeDelmitedTo()”的java应用程序发送的

经过一些研究,我已经发现了这个代码,可以从套接字读取消息,解码并解析它

data = sock.recv()
(size, position) = decoder._DecodeVarint(data, 0)
msg = MessageWrapper_pb2.WrapperMessage().ParseFromString(data[position:position + size])
我现在得到的是一个google.protobuf.message.DecodeError:截断的消息异常

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

编辑:

这就是对我有效的解决方案

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
def read_java_varint_delimited_流(sock):
buf=[]
data=sock.recv()
rCount=len(数据)
(大小、位置)=解码器。\u解码器变量(数据,0)
追加(数据)
当R计数<尺寸+位置时:
数据=sock.recv(尺寸+位置rCount)
rCount+=len(数据)
追加(数据)
返回b“”。联接(buf)、大小、位置
def读取消息(sock):
数据、大小、位置=读取\ java \变量\分隔\流(sock)
msg=MessageWrapper\u pb2.WrapperMessage()
msg.ParseFromString(数据[位置:位置+大小])
返回消息

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

假设发送了
变量
大小,然后发送数据。因此,读取
变量
,然后读取该字节数

更深入地说,描述如何通过使用字节的高位来标记延续来编码其值。我们可以编写自己的解码器

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)
导入结构
def read_java_varint_分隔的_流(sock):
sz=0
尽管如此:
vbyte,=struct.unpack('b',sock.recv(1))

sz=(vbyte)计算出的大小有问题,它总是非常大,因此循环永远不会结束。我稍微修改了函数(见上文)。