我有一个通过tcp传输gpb数据消息的应用程序。 tcp头是12个字节(msg_type,encode_type,msg_version,flags,msg_length)。然后我使用msg_length获取数据。
import json
import logging
from tornado.tcpserver import TCPServer
from tornado.iostream import StreamClosedError
from tornado import gen
from tornado.ioloop import IOLoop
from struct import Struct, unpack
from telemetry_pb2 import Telemetry
class TelemetryServer(TCPServer):
def __init__(self):
super().__init__()
self.header_size = 12
self.header_struct = Struct('>hhhhi')
self._UNPACK_HEADER = self.header_struct.unpack
@gen.coroutine
def handle_stream(self, stream, address):
print(f"Got connection from {address}")
while not stream.closed():
try:
header_data = yield stream.read_bytes(self.header_size)
msg_type, encode_type, msg_version, flags, msg_length = self._UNPACK_HEADER(header_data)
encoding = {1:'gpb', 2:'json'}[encode_type]
msg_data = b''
print(encode_type)
if encode_type == 1:
print(f'Got {msg_length} bytes from {address} with encoding {encoding}')
while len(msg_data) < msg_length:
packet = yield stream.read_bytes(msg_length - len(msg_data))
msg_data += packet
print(msg_data)
gpb_parser =Telemetry()
gpb_data = gpb_parser.ParseFromString(msg_data.decode('ascii'))
print(gpb_data.node_id)
else:
print(f'Got {msg_length} bytes from {address} with encoding {encoding}')
while len(msg_data) < msg_length:
packet = yield stream.read_bytes(msg_length - len(msg_data))
msg_data += packet
json_data = json.loads(msg_data.decode("ascii"))
except Exception as e:
print(e)
stream.close()
def main():
server = TelemetryServer()
server.bind(5556)
server.start(0)
IOLoop.current().start()
我得到的错误是数据是python bytes string
b'\n\x0fNCS5501-SE-LER1\x1a\t30seconds23Cisco-IOS-XR-ip-bfd-oper:bfd/ipv4-multi-hop-summary:\n2015-11-09@\xc8\x0cH\x92\x92\xa1\xf4\xa8,P\x92\x92\xa1\xf4\xa8,Zm\x08\x93\x92\xa1\xf4\xa8,z\x06\x12\x04keysz\\\x12\x07contentzQ\x12\rsession-statez\x0f\x12\x0btotal-count8\x00z\x0e\x12\ndown-count8\x00z\x0c\x12\x08up-count8\x00z\x11\x12\runknown-count8\x00h\x93\x92\xa1\xf4\xa8,'
'ascii' codec can't decode byte 0xc8 in position 94: ordinal not in range(128)
问题是如何将此字节字符串转换为字符串以便我可以解析它?
解决了它:
遥测对象不是解析器,它是完整的消息对象。所以可以做到
gpb_parser =Telemetry()
gpb_parser.ParseFromString(msg_data)
print(gpb_parser.node_id)
答案 0 :(得分:0)
您使用ascii
解码数据。但是数据的编码是不同的。使用数据的原始编码:
msg_data.decode(encode_type)