[3] transmission of protobuf data by python3 socket

I. communication protocol

As shown in the above figure, the user-defined length protocol of datalength+databytes is adopted, in which:
datalength: the data length (excluding its own length) of the immediately following databytes, accounting for 4 bytes
databytes: data content after protobuf 3.0 protocol data serialization, unlimited length
Two client and server code, and then my second article, as shown in the figure below, pay attention to the circle

Client code: ClientProtoTest.py

from socket import *
import google.protobuf
import TransportMessage_pb2
import WeChatOnlineNoticeMessage_pb2
import traceback
import google.protobuf.any_pb2
#from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
Id = 0

def HearBeatReq_bytes():
    print('Heartbeat packet data...')
    global Id
    Id+=1
    transportMessage = TransportMessage_pb2.TransportMessage()#Pay attention to the brackets,
    transportMessage.MsgType = 1010
    transportMessage.Id = Id
    transportMessage.AccessToken ="ac897dss"
    return transportMessage.SerializeToString()

def OnlineNotice_bytes():
    print('On-line notification...')
    global Id
    Id+=1
    transportMessage = TransportMessage_pb2.TransportMessage()#Pay attention to the brackets,
    transportMessage.MsgType = 1020
    transportMessage.Id = Id
    transportMessage.AccessToken ="ac897dss"

    weChatOnlineNotice = WeChatOnlineNoticeMessage_pb2.WeChatOnlineNoticeMessage()
    weChatOnlineNotice.WeChatId = "wxid_123456789"
    weChatOnlineNotice.WeChatNo = "qdj_cancle"
    weChatOnlineNotice.WeChatNick = "Nickname 001"
    weChatOnlineNotice.Gender = 0
    weChatOnlineNotice.Country = "China"
    
    transportMessage.Content.Pack(weChatOnlineNotice)

    return transportMessage.SerializeToString()

HOST = '192.168.0.100'
PORT = 11087
BUFSIZ =1024
ADDR = (HOST,PORT)

tcpCliSock = socket(AF_INET,SOCK_STREAM)
tcpCliSock.connect(ADDR)

while True:
    
    data1 = input('send data[0].Sign out;[1].Heartbeat bag;[2].On-line notification>')
    print(data1)
    if data1=='0':
        break
    if data1 =='1':
        hearBeat_data = HearBeatReq_bytes()
        byte_data = hearBeat_data
        byte_head = (len(byte_data)).to_bytes(4, byteorder='big')
        tcpCliSock.send(byte_head)
        tcpCliSock.send(byte_data)
    if data1 =='2':
        onlineNotice_bytes = OnlineNotice_bytes()
        byte_data = onlineNotice_bytes
        byte_head = (len(byte_data)).to_bytes(4, byteorder='big')
        tcpCliSock.send(byte_head)
        tcpCliSock.send(byte_data)

tcpCliSock.close()

Server code: ServerProtoTest.py

import socket
import google.protobuf
import google.protobuf.any_pb2
import TransportMessage_pb2
import WeChatOnlineNoticeMessage_pb2

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
HostPort = ('192.168.0.100',11087)
s.bind(HostPort)  #Bind address port
s.listen(5)  #Listen for up to 5 connection requests
while True:
    print('server socket waiting...')
    obj,addr = s.accept()  #Block wait link
    print('socket object:',obj)
    print('client info:',addr)
    while True:
        Head_data = obj.recv(4)  #Receive 4 bytes of data header,
        data_len = int.from_bytes(Head_data, byteorder='big')
        
        protobufdata = obj.recv(data_len)
        
        tmessage = TransportMessage_pb2.TransportMessage()
        tmessage.ParseFromString(protobufdata)
        i_id = tmessage.Id
        i_msgtype = tmessage.MsgType
        print('id:',i_id,'msgType:',i_msgtype)
        if i_msgtype==0:
            print('abnormal')
            break
        if i_msgtype==1010:
            print('Server received heartbeat packet...')
        if i_msgtype == 1020:
            print('Server receives online notification...')
            online = WeChatOnlineNoticeMessage_pb2.WeChatOnlineNoticeMessage()
            tmessage.Content.Unpack(online)
            print('WeChatNo:'+online.WeChatNo,'WeChatId:'+online.WeChatId,'WeChatNick:'+online.WeChatNick)

3. Demonstration of operation results:

Conclusion: the protobuf data needs to be transformed through the SerializeToString() function, sent through the socket.send function, and the data received by the server is transformed into protobuf data through the ParseFromString() function
Last article: [2] use of python protobuf generic class Any
Next article: [4] the python 3 socket thread processes protobuf data

Tags: socket Google Python

Posted on Tue, 05 Nov 2019 07:41:48 -0800 by Jalz