可扩展多线程异步Socket服务器框架EMTASS 2.0

EMTASS 2.0是一个设计精巧的服务器框架,采用三个核心线程(客户端连接侦听、数据包处理、会话表检测)和异步处理模式,确保高效且可扩展。类架构中包含抽象类和泛型类,如TSessionBase和TDatabaseBase,允许根据业务需求进行定制。系统通过事件参数类型结构图和会话状态、断开类型枚举实现精细控制。
摘要由CSDN通过智能技术生成
(原创文章,转载请注明来源:http://blog.csdn.net/hulihui)

0 前言

>>[前言][第1节][第2节][第3节][第4节][第5节][第6节]

在程序设计与实际应用中,Socket数据包接收服务器够得上一个经典问题了:需要计算机与网络编程知识(主要是Socket),与业务处理逻辑密切(如:包组成规则),同时还要兼顾系统运行的稳定、效率、安全与管理等。具体应用时,在满足业务处理逻辑要求的基础上,存在侧重点:有些需要考虑并发与效率,有些需要强调稳定与可靠等等。虽然.NET 2.0 Framework上的IOCP(I/O完成端口)异步技术可以有效解决并发等问题,但完全的异步模式也缺乏一些控制上的灵活性,例如:Socket暂停操作等。

本文介绍的是一个传统Socket数据包服务器解决方案,该方案改自笔者2005年底的一个交通部省级公路交通流量数据服务器中心(DSC)项目。当时.NET Framework 2.0 与 Visual Studio 2005 发布没多久,笔者接触C#的时间不长。于是Google了国内国外网,希望找点应用C#解决Socket通信问题的思路和代码。最后,找到了两篇帮助最大的文章:一篇是国人2005年3月写的Socket接收器框架—— 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(一)(分(一)、(二)两篇),该文应用了客户端Socket会话(Session)概念;另一篇是美国人写的,提出了多线程、分段接收数据包的技术方案,描述了多线程、异步Socket的许多实现细节,该文坚定了笔者采用多线程和异步方式处理Socket接收器的技术路线。第一个版本EMTASS 1.0(EMTASS,Extensible Multi-Thread Asynchronous Socket Server)于2006年初完成并投入使用。

今年暑假,笔者修改了原Socket接收服务器代码,即EMTASS 1.1。最近,又按框架的可扩展性、可重用性等要求重新构思和设计了EMTASS,即EMTASS 2.0。下面的介绍共分六个部分:
  1. 总体思路与架构
  2. 关键实现技术
  3. 框架使用简介
  4. 一般测试结果
  5. 总结与展望
  6. 版本与源码

1 总体思路与架构

>>[前言][第1节][第2节][第3节][第4节][第5节][第6节]

1.1 总体思路

总体构思上,主要考虑多线程、异步Socket和可扩展性三个方面。

1) 三个核心线程

在Internet环境下的Socket应用中,客户端和网络容易出现异常,此时必须释放异常退出的Socket资源。考虑到服务器的高并发能力,一般采取包接收和处理分开的策略:将接收到的包添加到包队列,然后处理队列中的数据包。当然,侦听远程客户端的连接请求可以用Socket的AcceptAsync()异步方法(IOCP,I/O完成端口由此开始)。考虑到暂停、关闭同步操作,仍然用一个线程。这样,清理资源、处理数据包、侦停客户连接请求就是组成了EMTASS架构的三个核心线程,它们由.NET线程池统一管理:
  1. 客户端连接侦听线程 StartServerListen():循环侦听远程客户端的Socket连接请求。如果存在,通过适当规范性判断后创建该Socket的客户端会话TSessionBase对象(实际上是该类的派生类对象),同时调用该会话对象的Socket异步数据接收方法BeginReceive(),接收到的数据包存放在会话对象的包队列中。当然,新增的TSessionBase对象将添加到会话队列m_sessionTable(一个Dictionary<>泛型对象)中,该队列表就是清理和处理线程的遍历对象;
  2. 数据包处理线程 CheckDatagramQueue():循环检测TSessonBase队列中的会话对象,调用该对象的相关方法完成数据包解析、判断类型、数据存储等任务;
  3. 会话表检测线程 CheckSessionTable():循环检查会话表m_sessionTable中的各个会话对象,分步骤清理已经超时、无效或异常的会话对象,清理会话对象的缓冲区,释放其Socket资源。
2) 异步处理模式

.NET Framework中的Socket具有完整的异步处理能力:侦听后异步接收(AcceptAsync())、数据异步接收(BeginReceive())、数据异步发送(BeginSend())等。EMTASS框架采取了异步接收和发送方式,并封装在TSessionBase类中。在EMTASS的版本1.0、1.1中,这些方法在主类TSocketServerBase中实现,显然不符合类封装原则。

3) 系统可扩展性

可扩展性主要考虑不同的业务处理逻辑和应用场景,即:数据包格式、数据存储方法、数据库服务器等。框架EMTASS的可扩展性体现在类的泛型与抽象设计、方法虚拟和保护等方面:
  • 抽象类:会话基类TSessionBase、数据库基类TDatabaseBase均是抽象类,分别提供了数据包分析与判断、数据存储的虚拟方法;
  • 泛型类:主要基类TSocketServerBase有TSessionBase、TDatabaseBase两个泛型约束参数,可以根据这两个抽象类的派生类产生具体的服务器类型;
  • 方法抽象(abstract):TSessionBase的数据包分析方法AnalyzeDatagram()、TDatabaseBase的数据库打开方法Open()均是抽象的,必须在派生类中根据业务处理逻辑和数据库类型重写;
  • 方法保护(protected):与事件处理有关的方法、与业务处理逻辑相关的方法全部是protected方法,可以根据实际情况重写。

1.2 类架构

1)主要类层次结构

(图1 主要类层次关系)

按应用类别分,EMTASS主要有四组类:Socket服务器类、Session会话类、Database数据库类和枚举类型。
  • Socket服务器类
    • 服务器泛型类 TSocketServerBase:该类包括了一个服务器Socket对象、一个TDatabaseBase派生类对象、一个会话TSessionBase类派生对象的列表(Dictionary<>泛型对象),封装了TDatabaseBase、TSessionBase的全部事件,提供统一的对外公开接口和事件;
    • 泛型参数:服务器基类TSocketServerBase有两个泛型参数:TSessionBase类和TDatabaseBase类,定制它们的派生类后可以确定泛型类的具体版本。
  • 客户端会话类
    • 会话核心成员类 TSessionCoreInfo:是TSessionBase的基类,包括会话的核心字段:登录时间、最近会话时间、IP地址、客户端名、对象状态等,是会话列表清单和事件参数的基类之一。该类的成员字段全部是protected的,需要在派生类中赋予具体值;
    • 抽象会话类 TSessionBase:封装了客户端Socket、数据接收缓冲区、数据包缓冲区、数据包队列等数据结构,包括了与客户端通信相关的全部方法:数据接收与发送、数据包处理等。
评论 230
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值