基于Socket的十六进制数据解析
数据解析的思路
基本思路
- 消息结构体,存储从缓存中解析的数据; buffer
- 回调函数,从缓存中解析数据时调用;
- 循环队列,用于缓存接收到的数据;
关键实现: - 把接收到的数据存储到缓存中,并准备解析;
- 递归解析消息
客户端和服务器端
-
首先定义一个类存放消息中包含的信息;是实体类;类中包括客户端和服务端的两种消息;
或者客户端和服务端分开写两个实体类存放消息; -
根据一定的协议对其编解码,定义一个interface,提供序列化和反序列化方法,
(1)toWire()根据一个特定的消息,将消息转换成字节序列;
(2)formWire()根据相同的协议,对给定的字节序列解析,根据信息的内容返回一个消息类的实例; -
实现接口的两个类,一个基于文本的编码方式,一个基于十六进制的编码方式;
- 基于文本的编码方式:
使用ASCII字符集对文本进行编码,消息开头是一个字符序列,用于快速将协议的消息和网 络中随机的垃圾消息区分开;
对射发送/接收消息的布尔值,是否为服务器发送响应消息,标记对射的ID,编码成十进制;
(1) toWire()简单的创建了一个字符串,该字符串包含了消息的所有字段,并通过空白符隔开。
(2)fromWire()首先检查魔术字符串,如果在消息前没有魔术字符串,则抛出一个异常。
注意程序对来源与网络的消息数据进行输入!
- 基于文本的编码方式:
- 基于十六进制的编码
基于十六进制对消息进行编码的程序,与文本编码相反,十六进制使用固定大小的消息,每条消息由一个特殊的字节开始,该字节最高X位为一个魔术值,该字节的哪几位对布尔值进行了编码,消息的哪几个字节总是不变,消息的哪几个字节是ID值,只有响应消息的哪几个字节包含数据信息,字节序列的格式如下:
<“id”><#acct>
其中 = [#acct|event gg zone ] or
当事件类型为NULL/ACK/DUH时data段为[]。当事件类型为ADM-CID时data段格式为[#acct|event gg zone];
第一个<#acct>为主机账号;
第一个<#acct>为安定宝ID;