当前位置:首页 > SuperSocket 1.6.4 通过FixedHeaderReceiveFilter解析自定义协议
SuperSocket 1.6.4 通过FixedHeaderReceiveFilter解析自定义协议
SuperSocket 提供了一些通用的协议解析工具, 你可以用他们简单而且快速的实现你自己的通信协议:
? TerminatorReceiveFilter (SuperSocket.SocketBase.Protocol.TerminatorReceiveFilter,
SuperSocket.SocketBase)
? CountSpliterReceiveFilter (SuperSocket.Facility.Protocol.CountSpliterReceiveFilter,
SuperSocket.Facility)
? FixedSizeReceiveFilter (SuperSocket.Facility.Protocol.FixedSizeReceiveFilter,
SuperSocket.Facility)
? BeginEndMarkReceiveFilter (SuperSocket.Facility.Protocol.BeginEndMarkReceiveFilter,
SuperSocket.Facility)
? FixedHeaderReceiveFilter (SuperSocket.Facility.Protocol.FixedHeaderReceiveFilter,
SuperSocket.Facility) 由于本次项目涉及的通信协议是头部格式固定并且包含内容长度的协议这里主要讲解使用FixedHeaderReceiveFilter来拆解. 通信协议格式如下:
代码 68H DLC SEQ 68H C L DATA CS 16H 字节数 1 4 2 1 1 2 变长 1 1 说明 帧起始码 设备逻辑地址 主站地址与命令序号 帧起始码 控制码 数据长度(DATA长度) 数据内容 校验码 结束码 在FixedHeaderReceiveFilter,头部指数据内容之前的数据(即数据长度L之前的部分),以上协议可以知道,头部包含11个字节.
首先,根据协议的需要来定义自己的请求类型,先实现一个客户端请求的实体类RequestInfo,改RequestInfo类必须实现接口 IRequestInfo,该接口只有一个名为\的字符串类型的属性.SuperSocket设计了两个RequestInfo类:StringRequestInfo 和BinaryRequestInfo,这里我们自定义一个来GDProtocolRequestInfo实现:
using System;
using System.Collections.Generic; using System.Linq; using System.Text;
using SuperSocket.SocketBase.Protocol;
namespace GDServer {
public class GDProtocolRequestInfo : IRequestInfo {
///
/// [不使用] ///
public string Key { get; set; }
///
/// 设备逻辑地址 ///
public string DeviceLogicalCode { get; set; }
///
/// 命令序列号 ///
public string Seq { get; set; }
///
public string ControlCode { get; set; }
///
/// 数据长度 ///
public string Length { get; set; }
///
public string Data { get; set; }
///
public string Cs { get; set; }
///
//public string EntireFrame { get; set; } } }
然后设计基于类FixedHeaderReceiveFilter实现自己的接收过滤器GDProtocolReceiveFilterV2,主要实现GetBodyLengthFromHeader和ResolveRequestInfo方法,实现如下:
using System;
using System.Collections.Generic; using System.Linq; using System.Text;
using SuperSocket.SocketBase.Protocol; using SuperSocket.Facility.Protocol;// using SuperSocket.Common;//
namespace GDServer {
///
/// 广东规约过滤器V2,(帧格式为GDProtocolRequestInfo) ///
public class GDProtocolReceiveFilterV2 : FixedHeaderReceiveFilter
public GDProtocolReceiveFilterV2() : base(11) {
}
///
/// 获取数据域和结尾字节长度 ///
///
protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length) {
//length为头部(包含两字节的length)长度
//获取高位
byte high = header[offset + length - 1]; //获取低位
byte low = header[offset + length - 2]; int len = (int)high * 256 + low; return len + 2;//结尾有2个字节 }
///
/// 实现帧内容解析 ///
///
protected override GDProtocolRequestInfo ResolveRequestInfo(ArraySegment
GDProtocolRequestInfo res = new GDProtocolRequestInfo(); string entireFrame = BytesToHexStr(header.Array) + BytesToHexStr(bodyBuffer.CloneRange(offset, length)); //res.EntireFrame = entireFrame;
res.DeviceLogicalCode = entireFrame.Substring(2, 8); res.Seq = entireFrame.Substring(10, 4);
res.ControlCode = entireFrame.Substring(16, 2); res.Length = entireFrame.Substring(18, 4);
int dataLen = int.Parse(HEXtoDEC(ReverseHexString(res.Length))); res.Data = entireFrame.Substring(22, dataLen * 2); res.Cs = entireFrame.Substring(22 + dataLen * 2, 2); return res; }
///
/// 高低对调 ///
///
string ReverseHexString(string str) {
char[] buff = new char[str.Length]; for (int i = 0; i < str.Length; i += 2) {
buff[i] = str[str.Length - i - 2]; buff[i + 1] = str[str.Length - 1 - i]; }
string s = new string(buff); return s; }
///
共分享92篇相关文档