在章节6 我们实现了利用protbuffer进行数据传送。在实际传送过程中,我们往往还需要对数据添加一些额外的信息,以便接收方能正确处理该数据包。
对此,可采用一些符合自定义要求的结构。这里就以如下结构作为代表:
其中msgId代表该协议对应的消息Id, bodyLength表明body占用长度, serialNo对应请求序列号,sessionId,对应回话Id, from 表明来原, body表明真正携带的数据
注意:该结构只针对服务器之间的通信,对于服务器与客户端之间的通信需要在重新设计。
新增包结构类:PacketHead.h
- #ifndef __PACKET_HEAD_H__
- #define __PACKET_HEAD_H__
- #include <string.h>
- class PacketHead
- {
- public:
- typedef int8_t int8;
- typedef int16_t int16;
- typedef int32_t int32;
- typedef int64_t int64;
- typedef uint8_t uint8;
- typedef uint16_t uint16;
- typedef uint32_t uint32;
- typedef uint64_t uint64;
- PacketHead(uint16 msgId = 0, uint16 bodyLength = 0, uint32 serialNo=0,
- uint32 sessionId = 0, uint16 from = 0)
- : _msgId(msgId)
- , _bodyLength(bodyLength)
- , _serialNo(serialNo)
- , _sessionId(sessionId)
- , _from(from){}
- ~PacketHead(){}
- inline void DecodeHead(const char* buffer)
- {
- int offset = 0;
- memcpy(&_msgId, buffer, sizeof(_msgId));
- offset += sizeof(_msgId);
- memcpy(&_bodyLength, buffer + offset, sizeof(_bodyLength));
- offset += sizeof(_bodyLength);
- memcpy(&_serialNo, buffer + offset, sizeof(_serialNo));
- offset += sizeof(_serialNo);
- memcpy(&_sessionId, buffer + offset, sizeof(_sessionId));
- offset += sizeof(_sessionId);
- memcpy(&_from, buffer + offset, sizeof(_from));
- }
- inline void EncodeHead(char* buffer)
- {
- int offset = 0;
- memcpy(buffer, &_msgId, sizeof(_msgId));
- offset += sizeof(_msgId);
- memcpy(buffer + offset, &_bodyLength, sizeof(_bodyLength));
- offset += sizeof(_bodyLength);
- memcpy(buffer + offset, &_serialNo, sizeof(_serialNo));
- offset += sizeof(_serialNo);
- memcpy(buffer + offset, &_sessionId, sizeof(_sessionId));
- offset += sizeof(_sessionId);
- memcpy(buffer + offset, &_from, sizeof(_from));
- }
- enum{HeaderLength = 14};
- uint16 _msgId;
- uint16 _bodyLength;
- uint32 _serialNo;
- uint32 _sessionId;
- uint16 _from;
- };
- #endif
其中DecodeHead负责解包, EncodeHead负责打包。
同样对于Push而言 需要在发送数据之间进行打包工作,在Pull而言在接受到数据之后进行解包工作。
对于Push一段 需要在Protobuffer序列化之前进行如下操作:
- PushZmq* push = new PushZmq(url.c_str());
- //string sendContent = "Hello Pull.I am From Push!";
- PbMsgHello helloMsg;
- helloMsg.set_helloint(123456);
- helloMsg.set_hellostring("ni hao wang peng ");
- int length = helloMsg.ByteSize();
- char* buffer = (char*)malloc(length + PacketHead::HeaderLength);
- // 加头
- PacketHead packetHead(1,length,2,3,4);
- packetHead.EncodeHead(buffer);
- helloMsg.SerializeToArray(buffer + PacketHead::HeaderLength, length);
- push->Send(buffer, length + PacketHead::HeaderLength);
- free(buffer);
对于Pull而言,在接受到的地方进行解包:
- LOG(INFO) << "TestOnMessage:";
- // 解包
- PacketHead packetHead;
- packetHead.DecodeHead(buffer);
- LOG(INFO) << " msgId = " << packetHead._msgId
- << " bodylength = " << packetHead._bodyLength
- << " serialNo = " << packetHead._serialNo
- <<" sessionId = " << packetHead._sessionId
- << " from = " << packetHead._from;
- PbMsgHello helloMsg;
- helloMsg.ParseFromArray(buffer + PacketHead::HeaderLength, packetHead._bodyLength);
- LOG(INFO) << " helloInt = " << helloMsg.helloint()
- << " helloString = " << helloMsg.hellostring();
重新编译运行
Pushl端:
Pull端:
在Pull端可以看到 在Push端之前打包的信息msgId bodyLength等均已解析出来。
打包 解包完毕。 对应源码:http://download.csdn.net/detail/jcracker/6270973
下一步应该加入framework来处理接受到的消息。