`
guaishou
  • 浏览: 167683 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

高性能 Windows Socket 服务端与客户端组件(源代码及测试用例下载)

    博客分类:
  • C++
阅读更多

 

  自从本座发表了两篇关于 Windows Socket 通信组件实现的文章后,收到不少读者的留言,希望能分享完整的源代码。此时,本座不敢弊帚自珍。特意在此提供服务端组件和客户端组件的完整代码。另外,为便于读者学习和理解,花了一点点时间精心制作了两个测试用例,一个用于功能测试(TestEcho),另一个用于性能测试(TestEcho-PFM)。读者可以通过这两个测试用例入手,迅速掌握组件的使用方法。希望对大家有所帮助,谢谢 ~ ^_^ ~

 

  (轻踩这里,你懂的 ^_*

 


 

原文:《基于 IOCP 的通用异步 Windows Socket TCP 高性能服务端组件的设计与实现

 

设计概述

  服务端通信组件的设计是一项非常严谨的工作,其中性能、伸缩性和稳定性是必须考虑的硬性质量指标,若要把组件设计为通用组件提供给多种已知或未知的上层应用使用,则设计的难度更会大大增加,通用性、可用性和灵活性必须考虑在内。

  现以一个基于 IOCP 的通用异步 Windows Socket TCP 服务端组件为例子,讲述其设计与实现相关的问题,希望能引发大家的思考,对大家日后开展相关类似工作时有所帮助。关于通用性、可用性、Socket 模型选型以及接口模型的设计等问题已经在本座前段时间发表的《通用异步 Windows Socket TCP 客户端组件的设计与实现》中进行过阐述,此处就不再重复了。现在主要针对服务端通信组件的特点阐述设计其设计和实现相关的问题。

 

  一、线程结构

  与组件相关的线程有 3 种:使用者线程、Accept  线程和工作线程,其中后 2 种由组件实现。

    1. 使用者线程:通过调用 Start/Stop/Send 等组件方法操作组件的一个或多个线程,通常是程序的主线程或其它业务逻辑线程。
    2. Accept 线程:使用 AcceptEx() 接收客户端连接请求并创建 Client Socket 的线程,将其独立出来,实现为单独的线程将使组件的模块划分更清晰,更重要的是避免与业务逻辑和通信处理的相互影响。
    3. 工作线程:使用 GetQueuedCompletionStatus() 监听网络事件并处理网络交互的多个线程,工作线程处理完网络事件后会向上层应用发送 OnAccept/OnSend/OnReceive 等组件通知。工作线程的数量可以根据实际情况之行设置(通常建议为:CPU Core Number * 2 + 2)。

  注意:如果上层应用在接收到 OnAccept/OnSend/OnReceive 这些组件通知时直接进行业务逻辑处理并在其中操作组件,则工作线程也成为了使用者线程。另外,如果要处理的业务逻辑比较耗时,上层应用应该在接收到组件通知后交由其他线程处理。

 

  二、性能

  组件采用 Windows 平台效率最高的 IOCP Socket 通信模型,因此在通信接口的性能方面是有保证的,这里就不多说了。现在从组件的设计与实现的角度来来阐述性能的优化。组件在代码级别做了很多优化,一些看似多余或繁琐的代码其实都是为了性能服务;组件在设计方面主要采用了 2 中优化策略:缓存池和私有堆。

  1.  
    1. 缓存池:在通信的过程中,通常需要频繁的申请和释放内存缓冲区(TBufferObj)和 Socket 相关的结构体(TSocketObj),这会大大影响组件的性能,因此,组件为 TBufferObj 和 TSocketObj 建立了动态缓存池, 只有当缓存池中没有可用对象时才创建新对象,而当缓存对象过多时则会压缩缓存池。
    2. 私有堆(Private Heap):在操作系统中,new / malloc 等操作是串行化的,虽然一般的应用程序不用太在乎这个问题,但是在一个高并发的服务器中则是个不可忽略的问题,另外 TBufferObj 和 TSocketObj 均为大小固定的结构体,因此非常适合在私有堆中分配内存,避免与 new / malloc 竞争同时又减少内存空洞。(关于私有堆的使用方法请参考这里 ^_^

 

  三、通用性与可用性

  与《通用异步 Windows Socket TCP 客户端组件的设计与实现》描述的客户端接口一样,服务端组件也提供了两组接口:ISocketServer 接口提供组件操作方法,由上层应用直接调用;IServerSocketListener 接口提供组件通知方法,由上层应用实现,这两个接口设计得非常简单,主要方法均不超过 5 个。由于组件自身功能完备(不需要附带其它库或代码)并且职责单一(只管通信,不参与业务逻辑),因此可以十分方便第整合到任何类型的应用程序中。

 

  四、伸缩性

  可以根据实际的使用环境要求设置工作线程的数量、 TBufferObj 和 TSocketObj 缓存池的大小、TBufferObj 缓冲区的大小、Socket 监听队列的大小、AccepEx 派发的数目以及心跳检查的间隔等。

 

  五、连接标识

  组件完全封装了所有的底层 Socket 通信,上层应用看不到任何通信细节,不必也不能干预任何通信操作。另外,组件在 IServerSocketListener 通知接口的所有方法中都有一个 Connection ID 参数,该参数作为连接标识提供给上层应用识别不同的连接。

 


 

原文:《通用异步 Windows Socket TCP 客户端组件的设计与实现

 

设计概述

  编写 Windows Socket TCP 客户端其实并不困难,Windows 提供了6种 I/O 通信模型供大家选择。但本座看过很多客户端程序都把 Socket 通信和业务逻辑混在一起,剪不断理还乱。每个程序都 Copy / Parse 类似的代码再进行修改,实在有点情何以堪。因此本座利用一些闲暇时光写了一个基于 IOCP 的通用异步 Windows Socket TCP 高性能服务端组件和一个通用异步 Windows Socket TCP 客户端组件供各位看官参详参详,希望能激发下大家的灵感。本篇文章讲述客户端组件。闲话少说,我们现在步入正题。

  • 最重要的第一个问题:如何才能达到通用?

  答:很简单。

    1、限制组件的职能,说白了,通信组件的唯一职责就是接受和发送字节流,绝对不能参与上层协议解析等工作。不在其位不谋其政就是这个意思。

    2、与上层使用者解耦、互不依赖,组件与使用者通过接口方法进行交互,组件实现 ISocketClient 接口为上层提供操作方法;使用者通过 IClientSocketListener 接口把自己注册为组件的 Listener,接收组件通知。因此,任何使用者只要实现了 IClientSocketListener 接口都可以使用组件;另一方面,你甚至可以自己重新写一个实现方式完全不同的组件实现给使用者调用,只要该组件遵从 ISocketClient 接口。这也是 DIP 设计原则的体现(若想了解更多关于设计原则的内容请猛击这里 ^_^)。

 

  • 最重要的第二个问题:可用性如何,也就是说使用起来是否是否方便?

  答:这个问题问得很好,可用性对所有通用组件都是至关重要的,如果太难用还不如自己重头写一个来得方便。因此,ISocketClient 和 IClientSocketListener 接口设计得尽量简单易用(通俗来说就是“傻瓜化”),这两个接口的主要方法均不超过 5 个。

 

  • 最重要的第三个问题:组件的性能如何?

  作为底层的通用组件,性能问题是必须考虑的,绝对不能成为系统的瓶颈。而另一方面,从实际出发,毕竟只是一个客户端组件,它的并发性要求远没有服务端那么高。因此,组件在设计上充分考虑了性能、现实使用情景、可用性和实现复杂性等因素,确保满足性能要求的同时又不会写得太复杂。做出以下两点设计决策:

  1.  
    1. 在单独线程中实现 Socket 通信交互。这样可以避免与主线程或其他线程相互干扰。
    2. I/O 模型选择 WSAEventSelect。细说一下选择这种 I/O 模型的原因:(各种 I/O 模型的性能比较可以参考:《Windows 网络编程(中文第二版)》第 154 页)
      • 阻塞模型:(不解析,你懂的^_^)
      • 非阻塞模型:(性能太低)
      • WSAAsyncSelect: (两个原因:a、性能太低;b、对于纯 Console 程序还要背负 HWND 实在是伤不起呀!)
      • 重叠 I/O:(有点复杂了)
      • 完成端口:(何必呢?)

分享到:
评论

相关推荐

    FTP服务端和客户端代码.zip

    在这个名为"FTP服务端和客户端代码.zip"的压缩包中,可能包含有实现FTP功能的源代码,用于帮助开发者理解和构建自己的FTP服务和客户端应用。 FTP服务端是服务器端的软件,负责监听来自客户端的连接请求,处理文件...

    supersocket基本类库与测试

    可测试多次”,这表明此压缩包可能包含了SuperSocket的示例代码或测试项目,帮助开发者学习如何设置Socket服务端和客户端,并进行反复测试以确保功能稳定。Socket服务端是接收和处理客户端连接请求的程序,而Socket...

    聊天工具用java编写的 包含客户端和服务端 并赠送源代码和可执行程序

    在聊天工具的实现中,客户端与服务端的通信通常基于TCP/IP协议的Socket编程。TCP是一种面向连接的、可靠的传输层协议,确保了数据的完整性和顺序性。客户端通过创建Socket连接到服务器,发送消息,并接收服务器的...

    C#使用SuperSocket实现自定义协议实现CS架构服务器和客户端程序设计).zip

    8. **测试和调试**:为了确保服务器和客户端的正确性,开发者通常会编写测试用例,模拟不同的场景进行测试,如并发连接测试、大数据包传输测试等。Visual Studio等IDE工具提供了丰富的调试功能,便于定位和修复代码...

    简单的基于MFC的Socket点对点对话客户端

    1. **源代码**:可能包含了使用MFC库编写的C++源代码,包括主程序文件、Socket通信相关的类定义、事件处理函数等。 2. **资源文件**:可能包含GUI界面的设计,如对话框模板、图标、菜单资源等,这些通常以`.rc`文件...

    C语言socket实现2人即时聊天系统_Linux服务器端Windows客户端

    参考本代码可熟悉socket基本使用方法、文件传输的基本功能实现,以及包含简单... 目录: code:源代码目录及工程可执行文件。 测试用例:包含正常功能,及非法入参测试,试用可执行文件功能时可参考截图中的参数下发。

    TCP异步客户端+服务端(稳定版本,支持大量上线及批量离线)

    ChattingSolution压缩包很可能包含了完整的源代码,包括客户端和服务器的项目文件,以及可能的测试用例和配置文件。开发者可以借此学习如何构建可扩展的TCP网络服务,并了解异步编程在实际项目中的应用。对于想要...

    java制作的聊天工具服务端源码

    8. **单元测试**:JUnit或TestNG可能用于编写服务端功能的测试用例,确保代码的正确性。 9. **版本控制**:可能使用Git进行版本控制,以便团队协作和代码管理。 10. **部署与运行**:服务端程序可能需要打包成JAR...

    apache_mina_maven 客户端测试程序

    Apache MINA 是一个高度可扩展的网络应用框架,主要用于简化开发高性能、高可用性的网络服务器和客户端应用程序。MINA 提供了一种与传输协议无关的抽象层,允许开发者使用相同的 API 来处理 TCP/IP(如 Socket)和 ...

    仿atm程序源代码

    【仿ATM程序源代码】是一个模拟实际自动取款机(ATM)功能的软件项目,旨在帮助用户理解和学习如何构建一个基本的银行系统。这个程序主要包括客户端和服务端两部分,实现了用户登录、账户操作以及交互式的声音提醒等...

    重叠IO服务端案例

    3. **Windows Socket API**:服务端程序会使用Winsock库提供的API,如`accept`来接受新的客户端连接,`recv`和`send`来接收和发送数据,以及`WSAAsyncSelect`或`WSAEventSelect`来设置异步I/O。 4. **多线程或IOCP...

    C#程序开发范例宝典源代码14(共20章)

    14. **单元测试与调试**:源代码可能包含 NUnit 或 MSTest 的单元测试用例,以及调试技巧,帮助开发者确保代码质量。 通过《C#程序开发范例宝典源代码14》的学习,开发者不仅可以巩固C#的基础知识,还能深入理解...

    Go实现socket.io-emitter-Go-下载

    在压缩包子文件的文件名称列表 "socket.io-go-emitter-master" 中,我们可以推测这是项目的源代码仓库,可能包含了主代码文件、测试文件、示例、文档等资源。"master"分支通常是开源项目的主要开发分支,这意味着...

    JAVA网络通信系统的研究与开发(源代码+开题报告).zip

    而集成测试工具如JMeter则可用于性能测试和压力测试,检查系统在高负载下的表现。 通过这个项目,你可以深入理解Java网络编程的各个方面,并有机会实践如何将理论知识应用于实际系统开发中。开题报告将指导你进行...

    Java课程设计案例精编源代码

    7. **网络编程**:Java的Socket编程允许创建客户端和服务端应用,进行数据交换。部分案例可能涉及TCP/IP通信或HTTP协议的实现。 8. **GUI编程**:如果源码包含图形用户界面,那么会涉及到Swing或JavaFX库,如JFrame...

    JAVA局域网飞鸽传书软件设计与实现(源代码+论文).zip

    8. **测试与调试**:源代码中应包含单元测试和集成测试,帮助验证代码的正确性。通过查看测试用例,可以学习如何编写测试代码。 9. **论文中的理论分析**:论文部分会涉及软件工程的相关理论,如需求分析、系统设计...

    Java案例开发集j源代码

    6. **网络编程**:Java的Socket编程可用于创建客户端和服务端的网络通信。在源代码中,你可能发现ServerSocket、Socket、DataInputStream和DataOutputStream的使用。 7. **GUI编程**:Java的Swing和JavaFX库提供了...

    基于PYTHON实现的软件缺陷检测程序研究.pdf

    软件缺陷检测程序通常包括几个关键部分,例如源代码预处理、测试驱动生成、测试用例的生成和执行以及测试结果的汇总与分析。Python能够处理源代码文件,利用其字典数据结构,实现信息的快速提取和存储,便于对软件...

    java开源代码 捕鱼游戏

    【Java开源代码 捕鱼游戏】 在Java编程领域,捕鱼游戏是一种常见的娱乐应用程序,它通常结合了游戏逻辑、图形渲染、...通过研究这个项目的源代码,开发者可以深入理解Java在网络游戏开发中的应用,提升自己的技能。

    HAHA CHAT Java仿QQ聊天程序源代码.7z

    【标题】中的“HAHA CHAT Java仿QQ聊天程序源代码.7z”是一个使用Java编程语言开发的聊天应用程序的源代码压缩包。这个程序旨在模仿QQ聊天软件的功能,为用户提供即时通讯的能力。 【描述】中提到的“HAHA CHAT ...

Global site tag (gtag.js) - Google Analytics