一、通讯协议
如上图,采用 datalength+databytes 的自定义长度的协议,其中:
datalength:紧跟其后的databytes的数据长度(不包含自身长度),占4字节
databytes:protobuf 3.0协议数据序列化后的数据内容,长度不限
二 客户端和服务器端代码,接着我的第二篇文章,如下图,注意圈起来的地方
客户端代码: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('心跳包数据...')
global Id
Id+=1
transportMessage = TransportMessage_pb2.TransportMessage()#注意括号不要掉了,
transportMessage.MsgType = 1010
transportMessage.Id = Id
transportMessage.AccessToken ="ac897dss"
return transportMessage.SerializeToString()
def OnlineNotice_bytes():
print('上线通知...')
global Id
Id+=1
transportMessage = TransportMessage_pb2.TransportMessage()#注意括号不要掉了,
transportMessage.MsgType = 1020
transportMessage.Id = Id
transportMessage.AccessToken ="ac897dss"
weChatOnlineNotice = WeChatOnlineNoticeMessage_pb2.WeChatOnlineNoticeMessage()
weChatOnlineNotice.WeChatId = "wxid_123456789"
weChatOnlineNotice.WeChatNo = "qdj_cancle"
weChatOnlineNotice.WeChatNick = "昵称001"
weChatOnlineNotice.Gender = 0
weChatOnlineNotice.Country = "中国"
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('发送数据[0].退出;[1].心跳包;[2].上线通知>')
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()
服务器端代码: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) #绑定地址端口
s.listen(5) #监听最多5个连接请求
while True:
print('server socket waiting...')
obj,addr = s.accept() #阻塞等待链接
print('socket object:',obj)
print('client info:',addr)
while True:
Head_data = obj.recv(4) #接收数据头 4个字节,
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('异常')
break
if i_msgtype==1010:
print('服务器接收到心跳包...')
if i_msgtype == 1020:
print('服务器接收到上线通知...')
online = WeChatOnlineNoticeMessage_pb2.WeChatOnlineNoticeMessage()
tmessage.Content.Unpack(online)
print('WeChatNo:'+online.WeChatNo,'WeChatId:'+online.WeChatId,'WeChatNick:'+online.WeChatNick)
三 运行结果演示:
总结:protobuf数据最终需要通过SerializeToString()函数转化,通过socket.send函数发送出去,服务器端接收到的数据通过ParseFromString()函数转化成protobuf数据
上一篇:【2】python protobuf泛型类Any使用
下一篇:【4】python3 socket线程处理protobuf数据