SuperSocket 介绍
一、总体介绍
SuperSocket 是一个轻量级的可扩展的 Socket 开发框架,由江振宇先生开发。
官方网站:http://www.supersocket.net/
1、SuperSocket具有如下特点:
- 简单易用,只需要几个类就能创建出健壮的Socket服务器端程序
- 性能优良, 稳定可靠
- 支持各种协议, 内置的协议解析工具让你把实现通信协议这种复杂的工作变得很简单
- 自动支持SSL/TLS传输层加密
- 强大,灵活而且可扩展的配置让你开发Socket服务器省时省力
- 支持多个socket服务器实例运行, 而且支持多个服务器实例的隔离
- SuperSocket能以控制台或者Windows服务形式运行。一个脚本就能将SuperSocket安装成服务
- 灵活的日志策略能够记录大部分socket活动
- 支持UDP
- 支持IPv6
- 支持Windows Azure
- 支持Linux/Unix操作系统(通过Mono 2.10或以上版本)
- 内置可直接使用的Flash/Silverlight Socket策略服务器
2、SuperSocket应对项目需求特点:
- 开源,基于Apache 2.0协议,可以免费使用到商业项目.
- 高性能的事件驱动通信.
- 会话级别的发送队列能够让你通过会话并发的发送数据,并保持高性能和可控性.
- 强大且高性能的协议解析实现工具帮你简化了网络数据的分析工作.
- 轻量级意味着组件可以自由选择使用,可根据环境变化变更.
3、SuperSocket的架构和设计
可以在官方的中文文档查询到http://docs.supersocket.net/v1-6/zh-CN/Architecture-Diagrams
- 每个连接的客户端都以Session的方式管理,发送数据给客户端也通过Session的Send方法,
- 每个客户端发过来的数据流都经过ReceiveFilter过滤器(这里即可自定义协议或者使用自带的一些帧过滤器)到ReqestInfo。
- ReqestInfo包含了该条数据内容,当然如果是自定义的协议,可以实现自己的ReqestInfo,把数据包内容直接装入帧对象。
SuperSocket 层次示意图
SuperSocket层次解析:
- 设备层:基于flash和SilverLight的策略服务器和基于接收过滤器的协议实施。
- 应用层:可扩展的应用程序服务:包括多种API集成。会话容器和命令框架。
- 套接字层: 通过传输协议TCP和UDP的事件驱动套接字服务。
SuperSocket 请求处理模型示意图
模型解析:
- 客户端携带数据流与Server端Socket Listener建立连接之后,SuperSocket 服务就将这一个连接视为一个Session会话。表示客户端和服务器端的一个逻辑连接,数据的收发都是在这个Session中进行处理的(此过程中的数据流为二进制数据)。
- 携带数据流的Session通过默认或者自定的接受过滤器将过滤后的数据传递到RequestInfo对象。每一个客户端对象都得实例化一个RequestInfo类,将接收到的二进制流转换成请求的实例。
- 根据RequestInfo执行Command命令,一个Command 包含一个Session和RequestInfo,在Command中根据需求解析数据。也可通过Session向客户端发送数据,例如有些DTU或者RTU设备需要发送指令才能返回数据。
SuperSocket 对象模型图示意图
模型解析:
- 应用服务AppServer 包括命令Commands, 会话容器Session contaioner。
- 对象层次:基本配置Config->命令过滤器Command Filters->日志和日志工厂Log/LogFactory->命令装载机CommandLoaders->接收过滤器工厂ReceiveFilterFactory->连接过滤Connection Filters。
- Socket 服务:多客户端监听,TCP1 、TCP2、。。。。UDP。
4、SuperSocket内置的常用协议实现模版
为了减少码农的工作量,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)
以上模板的使用可参考官方文档http://docs.supersocket.net/v1-6/zh-CN/The-Built-in-Common-Format-Protocol-Implementation-Templates
5、通过请求处理模型可以总结基本的开发流程
- 实例化AppServer对象,时刻监听客户端的会话。
- 定义RequestInfo实体类型,接收和处理二进制字符流。
- 定义数据接收过滤器,ReceiveFilter,接收过滤后的数据,并将数据赋值给RequestInfo实体类型。
- 在appServer的构造函数中继承使用接收过滤工厂RequestFilterFactory,并执行自定的ReceiveFilter和RequestInfo。
- 在1的数据请求委托事件中解析并使用RequestInfo实体中对应的数据。
二、通过FixedHeaderReceiveFilter解析自定义协议
自定义自己服务器中相关的类,建议类的建立顺序:RequestInfo>ReceiveFilter>AppSession>AppServer
通信协议格式如下:
在FixedHeaderReceiveFilter,头部指数据内容之前的数据(即数据长度L之前的部分),以上协议可以知道,头部包含11个字节.
1、自定义请求类型RequestInfo
先实现一个客户端请求的实体类RequestInfo,该RequestInfo类必须实现接口 IRequestInfo,该接口只有一个名为"Key"的字符串类型的属性。
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
{
/// <summary>
/// [不使用]
/// </summary>
public string Key { get; set; } /// <summary>
/// 设备逻辑地址
/// </summary>
public string DeviceLogicalCode { get; set; } /// <summary>
/// 命令序列号
/// </summary>
public string Seq { get; set; } /// <summary>
/// 控制码
/// </summary>
public string ControlCode { get; set; } /// <summary>
/// 数据长度
/// </summary>
public string Length { get; set; } /// <summary>
/// 数据域
/// </summary>
public string Data { get; set; } /// <summary>
/// CS校验
/// </summary>
public string Cs { get; set; } /// <summary>
/// 当前完整帧
/// </summary>
//public string EntireFrame { get; set; }
}
}
2、自定义接收过滤器ReceiveFilter
设计基于类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
{
/// <summary>
/// 广东规约过滤器V2,(帧格式为GDProtocolRequestInfo)
/// </summary>
public class GDProtocolReceiveFilterV2 : FixedHeaderReceiveFilter<GDProtocolRequestInfo>
{
public GDProtocolReceiveFilterV2()
: base()
{ } /// <summary>
/// 获取数据域和结尾字节长度
/// </summary>
/// <param name="header"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
/// <returns></returns>
protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length)
{
//length为头部(包含两字节的length)长度 //获取高位
byte high = header[offset + length - ];
//获取低位
byte low = header[offset + length - ];
int len = (int)high * + low;
return len + ;//结尾有2个字节
} /// <summary>
/// 实现帧内容解析
/// </summary>
/// <param name="header"></param>
/// <param name="bodyBuffer"></param>
/// <param name="offset"></param>
/// <param name="length"></param>
/// <returns></returns>
protected override GDProtocolRequestInfo ResolveRequestInfo(ArraySegment<byte> header, byte[] bodyBuffer, int offset, int length)
{
GDProtocolRequestInfo res = new GDProtocolRequestInfo();
string entireFrame = BytesToHexStr(header.Array) + BytesToHexStr(bodyBuffer.CloneRange(offset, length));
//res.EntireFrame = entireFrame;
res.DeviceLogicalCode = entireFrame.Substring(, );
res.Seq = entireFrame.Substring(, );
res.ControlCode = entireFrame.Substring(, );
res.Length = entireFrame.Substring(, );
int dataLen = int.Parse(HEXtoDEC(ReverseHexString(res.Length)));
res.Data = entireFrame.Substring(, dataLen * );
res.Cs = entireFrame.Substring( + dataLen * , );
return res;
} /// <summary>
/// 高低对调
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
string ReverseHexString(string str)
{
char[] buff = new char[str.Length];
for (int i = ; i < str.Length; i += )
{
buff[i] = str[str.Length - i - ];
buff[i + ] = str[str.Length - - i];
}
string s = new string(buff);
return s;
} /// <summary>
/// 16进制转10进制
/// </summary>
/// <param name="HEX"></param>
/// <returns></returns>
string HEXtoDEC(string HEX)
{
return Convert.ToInt64(HEX, ).ToString();
} /// <summary>
/// 转化bytes成16进制的字符
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
string BytesToHexStr(byte[] bytes)
{
string returnStr = "";
if (bytes != null)
{
for (int i = ; i < bytes.Length; i++)
{
returnStr += bytes[i].ToString("X2");
}
}
return returnStr;
}
}
}
3、自定义的AppSession
先创建新的AppSession,GDProtocolSessionV2,新的AppServer将使用它。
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Protocol;
using System; namespace GDServer
{
public class GDProtocolSessionV2 : AppSession<GDProtocolSessionV2, GDProtocolRequestInfo>
{
protected override void HandleException(Exception e)
{ }
}
}
4、自定义AppServer
使用该协议的方法是使用接收或者自己定义的接收过滤器工厂来在 SuperSocket 中启用该协议
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Protocol; namespace GDServer
{
public class GDProtocolServerV2 : AppServer<GDProtocolSessionV2, GDProtocolRequestInfo>
{
public GDProtocolServerV2()
: base(new DefaultReceiveFilterFactory<GDProtocolReceiveFilterV2, GDProtocolRequestInfo>()) //使用默认的接受过滤器工厂 (DefaultReceiveFilterFactory)
{
}
}
}
5、测试程序
这样,GDProtocolServerV2就完成了,下面是测试代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GDServer;
namespace Test
{
class Program
{
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Red;
var gdServer = new GDProtocolServerV2();
gdServer.Setup();
gdServer.NewSessionConnected += gdServer_NewSessionConnected;
gdServer.NewRequestReceived += gdServer_NewRequestReceived;
gdServer.SessionClosed += gdServer_SessionClosed;
gdServer.Start();
Console.WriteLine("server is:" + gdServer.State.ToString());
while (true)
{
if (Console.ReadKey().KeyChar == 'q')
{
gdServer.Stop();
gdServer.Dispose();
return;
}
}
} static void gdServer_SessionClosed(GDProtocolSessionV2 session, SuperSocket.SocketBase.CloseReason value)
{
Console.WriteLine(session.RemoteEndPoint.ToString() + " closed. reason:" + value);
} static void gdServer_NewRequestReceived(GDProtocolSessionV2 session, GDProtocolRequestInfo requestInfo)
{
var info = requestInfo;
Console.WriteLine("receive from: " + session.RemoteEndPoint.ToString());
Console.WriteLine("DeviceLogicalCode:" + info.DeviceLogicalCode);
Console.WriteLine("Seq:" + info.Seq);
Console.WriteLine("ControlCode:" + info.ControlCode);
Console.WriteLine("Length:" + info.Length);
Console.WriteLine("Data:" + info.Data);
Console.WriteLine("Cs:" + info.Cs);
Console.WriteLine("-------------------------------------------------------------");
} static void gdServer_NewSessionConnected(GDProtocolSessionV2 session)
{
Console.WriteLine(session.RemoteEndPoint.ToString() + " connected.");
}
}
}
测试结果:
分别发送符合该协议格式的帧(用TCP调试助手使用hex方式发送)
68 77 77 12 34 00 01 68 A1 03 00 11 11 11 DC 16
68 77 77 12 34 41 01 68 01 0C 00 01 00 00 00 00 00 00 00 30 80 10 80 94 16
68 77 77 12 34 41 01 68 88 08 00 00 00 30 80 00 10 80 00 16 16
68 77 77 12 34 41 01 68 95 23 00 00 0B 00 00 10 00 00 00 00 00 FF FF FF FF FF FF FF FF 00 00 5B 00 00 00 00 00 00 00 00 00 00 00 00 00 32 9E 16
打印结果如下:
server is:Running
127.0.0.1:34360 connected.
receive from: 127.0.0.1:34360
DeviceLogicalCode:77771234
Seq:0001
ControlCode:A1
Length:0300
Data:111111
Cs:DC
-------------------------------------------------------------
receive from: 127.0.0.1:34360
DeviceLogicalCode:77771234
Seq:4101
ControlCode:01
Length:0C00
Data:010000000000000030801080
Cs:94
-------------------------------------------------------------
receive from: 127.0.0.1:34360
DeviceLogicalCode:77771234
Seq:4101
ControlCode:88
Length:0800
Data:0000308000108000
Cs:16
-------------------------------------------------------------
receive from: 127.0.0.1:34360
DeviceLogicalCode:77771234
Seq:4101
ControlCode:95
Length:2300
Data:000B0000100000000000FFFFFFFFFFFFFFFF00005B0000000000000000000000000032
Cs:9E
-------------------------------------------------------------以上代码请自行引入SuperSocket的dll和System.configuration.dll
本文由http://www.cnblogs.com/xiepeixing/原创,转载请著名出处
三 、SuperSocket 1.6 中文文档
http://docs.supersocket.net/v1-6/zh-CN
四、入门教程
https://www.cnblogs.com/fly-bird/category/938912.html
五、入门实例下载
链接:https://pan.baidu.com/s/1-Q0a4wsNcwyJI7_D0sbsXw 密码:zda7
SuperSocket 介绍的更多相关文章
- C#网络编程技术SuperSocket实战项目演练
一.SuperSocket课程介绍 1.1.本期<C#网络编程技术SuperSocket实战项目演练>课程阿笨给大家带来三个基于SuperSocket通讯组件的实战项目演示实例: ● 基于 ...
- SuperSocket.ClientEngine介绍
项目地址:https://github.com/kerryjiang/SuperSocket.ClientEngine 其中需要引入的SuperSocket.ProtoBase项目:SuperSock ...
- 基于SuperSocket的IIS主动推送消息给android客户端
在上一篇文章<基于mina框架的GPS设备与服务器之间的交互>中,提到之前一直使用superwebsocket框架做为IIS和APP通信的媒介,经常出现无法通信的问题,必须一天几次的手动回 ...
- 开源项目SuperSocket的学习笔记
近几日想在一个项目中引进一个Socket Server,用来接收客户端发送的命令消息并根据具体的业务逻辑对消息进行处理,然后转发给其它在线的客户端.因为以前在博客园关注过江大渔开源的SuperSock ...
- SuperSocket与Netty之实现protobuf协议,包括服务端和客户端
今天准备给大家介绍一个c#服务器框架(SuperSocket)和一个c#客户端框架(SuperSocket.ClientEngine).这两个框架的作者是园区里面的江大渔. 首先感谢他的无私开源贡献. ...
- SuperSocket源码解析之启动过程
一 简介 这里主要说明从配置系统引导启动SuperScoekt作为应用程序,且以控制台程序方式启动 二 启动过程 2.1 配置解析 从读取配置文件开始,直接拿到一个SocketServiceConfi ...
- SuperSocket源码解析之开篇
一 简介 官方介绍:SuperSocket 是一个轻量级, 跨平台而且可扩展的 .Net/Mono Socket 服务器程序框架.你无须了解如何使用 Socket, 如何维护 Socket 连接和 S ...
- SuperSocket源码解析之开篇 (转)
一 简介 官方介绍:SuperSocket 是一个轻量级, 跨平台而且可扩展的 .Net/Mono Socket 服务器程序框架.你无须了解如何使用 Socket, 如何维护 Socket 连接和 S ...
- 初识SuperSocket
有一些企业由于以前使用的操作系统是被淘汰的操作系统,例如OpenVMS.现需要将针对openvms开发的通讯程序进行移植到现在的windows操作系统上,通过一段时间的了解,现在需要花时间去找商业性的 ...
随机推荐
- vim操作命令备忘
vim操作命令备忘 查找/替换 :%s/keyword//gn //搜索匹配的关键词数量 :%s/keywords/target //替换关键词 待续……
- springboot主从数据库
是从springmvc的思路上来做的,主要就是配置主.从DataSource,再继承AbstractRoutingDataSource,重写determineCurrentLookupKey方法,通过 ...
- 《Think Python》第17章学习笔记
目录 <Think Python>第17章学习笔记 17.1 面向对象的特性(Object-oriented features) 17.2 打印对象(Printing objects) 1 ...
- 【转载】2012年七个免费ASP空间分享-支持ASP、ASP.NET的空间
文章目录 Azure空间 Appharbor 7host空间 Brinkster Jabry空间 总结后的话 这篇免费ASP空间的总结文章本来标题已经拟好了是:2012年十大免费ASP空间分享,但是当 ...
- ROS:消息发布器和订阅器(c++)
学习资料主要源自http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29 $ roscd beginner_t ...
- 01-Web客户端与服务器详解
1.CS与BS 软件使用方式上两种划分 C/S架构 Client/ServerPC客户端.服务器架构 特点: 在服务器当中就主要是一个数据库,把所有的业务逻辑以及界面都交给客户端完成 优点: 较为安全 ...
- Spring部分面试知识
对Spring的理解 spring是一个轻量级的开源框架,贯穿持久层.业务逻辑层.控制层.让每一个功能模块都可以独立的分开,降低耦合度,提高代码复用度.spring通过控制反转降低耦合性,一个对象的依 ...
- [SCOI2009]粉刷匠
线性DP预处理+分组背包 首先设dp[i][j][0/1]表示该木板前i个格刷了j次且最后一次颜色为0/1的最大正确数 做下0/1的前缀和然后转移状态 dp[i][j][k]=max(dp[l][j] ...
- 原型链中的prototype、__proto__和constructor的关系
先来看一张图,这张图可以说是围绕以下代码完整的描述了各对象之间的关系.接下来我们来看看如何一步步画出这张图. function Foo(){}; var foo = new Foo(); 首先,明确几 ...
- vue-router初涉
概念: vue-router: vue官方路由插件. 路由: 指单页面应用的路径管理系统.在vue中都是单页应用,相当于只有一个index.html页面,所以无法使用<a>标签,我们使用路 ...