基于Boost.Asio的异步通信服务器设计与开发



boost::asio 通讯服务器实践

 

1. 开发环境搭建

1.1. Asio准备

万事开头难。对于一个C++的陌生者,编译一个开源的代码并不是一件轻松愉快的事情。为使大家在审阅和检测本代码可使用性时没有必要花费太多时间和精力去编译Boost::Asio库,在此把我在编译boost库时不愉快的经历记录下来,供参考。使用Asio有两种方式,一种是直接使用Asio库,到网站:

https://sourceforge.net/projects/asio/files/asio/1.11.0%20%28Development%29/可以下载单独的Asio库,目前最新版本为1.11。另一种是使用boost.asio库,该库依赖于Boost.System库,因此需要把下载后的boost源码编译生成相应的库才能使用。Boost下载地址http://www.boost.org/,目前最新版本为1.61.0. 我下载的版本为1.61.0版本。下载后解压到E:\boost1610目录下.

1.2. Qt准备

Qt官网上下载Qt。我电脑环境是联想TIANYI 100,4G内存,安装的windwos10笔记本开发,因此下载的是windows版本的Qt5.7版本,安装比较简单,按照提示实行“下一步”就可以。

1.3. 编译boost

编译boost比较麻烦一点,使用Qt自带的mingw编译boost步骤如下:

  1. 配置mingw的系统环境变量PATH。我把QT安装在C盘下,path值配置为:C:\Qt\Qt5.6.1\Tools\mingw492_32\bin。配置后再命令行中输入gcc -v 如果配置成功,则显示为:(配置完后,我试着在命令行中输入gcc -v,居然提示gcc不是内部命令。然后把电脑重起,再输入gcc -v,这次显示成功)。

  2. 下载boost后,解压到任意目录下我的解压目录为E:\boost1610;

  3. 打开cmd.exe,切换到E:\boost1610目录下,在命令行中实行bootstrap.bat gcc 生成b2.exe和bjam.exe。Bootstrap.bat 是在Windows下生成自己的bjam.exe 和b2.exe 的脚本。 在Linux下是bootstrap.sh.  Bootstrap.bat gcc命令实行完成后,会在QT解压的目录下生成bjam.exe 和b2.exe这两个文件.


     

  4. 实行b2.exe开始编译。这个命令会生成一个bin.v2的文件夹,为下一步通过bjam命令提供链接。

  5. 在命令行窗口下实行bjam "toolset=gcc" install编译boost源代码。表示将编译结果默认保存到C:\boost目录下或者指定目录 bjam.exe “-sTools=mingw” --prefix=d:\boost install 或者 Bjam.exe --prefix=d:\boost toolset=gcc install 来编译boost。编译完成后会看到D:\boost文件夹下面有两个子目录 include 和lib。 实行这个命令过程非常耗时,慢慢等待。

1.4. 使用boost库

方法一:

1、选择将这两个目录拷贝到mingw目录下的include和lib目录中,或者将这两个目录的路径添加到系统路径中。

2、由于在windows下系统默认的命名方式为libboost-iostreams-mgw44-mt-1-61-0.a 可以改为libboost-iostreams.a.  Mt 表示多线程,默认。

方法二:

建立Qt项目的时候,都会生成一个XXX.pro的文件,在该文件下增加如下代码:

#DEFINES += BOOST_THREAD_USE_LIB

INCLUDEPATH += E:\Boost\include\boost-1_61

#DEPENDPATH += E:\Boost\include\boost-1_61

LIBS += E:\Boost\lib\libboost_system-mgw49-mt-1_61.a

 

LIBS += -lpthread libwsock32 libws2_32

其中最后一行

LIBS += -lpthread libwsock32 libws2_32表示要用到windows的完成端口模型下的winsocket库。

建议使用方法二。

到此,开发环境基本搭建完成。下面开始Boost.Asio设计开发服务器软件。

2. Asio通讯服务器设计

2.1. 设计指标

  1. 跨平台,一套代码在不修改原代码基础上可运行于windows和Linux系统;

  2. 运行于Linux系统上时采用EPOLL模型,运行于Windows上时采用完成端口模型(IOCP),且并发连接量尽可能接近操作系统IO模型提供的理论并发量;

  3. 能接入任何通过TCP方式连接的客户端,不受任何具体协议数据包的限制;

  4. 客户端发送数据的时候,要求服务器应答时,服务器应答客户端时间应尽可能小,最低要求小于100毫秒。

  5. 有效管理服务器与客户端连接的生命周期

  6. 基础通讯与业务逻辑解耦。

2.2. 概要设计

由于跨平台要求,目前C++适合跨平台的第三方库有libevent、asio库等,我们决定采用asio库实现。服务程序由通讯服务类、连接类、连接管理类、业务接口模板类等四大类组成。为适应不同的客户端接入,服务程序不解析任何数据包,只接受客户端连接和接收客户端发送过来的数据。客户端连接成功后,调用连接器管理对象保存连接,同时向操作系统投递异步读事件,当客户端发送的数据到达服务器,调用连接器中的读事件读取数据,通过业务接口将数据传递到业务接口,数据的处理由业务接口进一步处理。客户端需要服务器应答的,由业务接口根据客户端与服务器端通讯协议格式构造应答数据包后,由连接器转发到客户端。

通讯服务类(TTcpServer):提供基础的端口监听监听,不处理任何业务逻辑,以达到通讯服务类通用的目的。对用户暴露接口有:

  1. SetIpAddress设置监听的IP地址和端口。

  2. SetRecycleSoketTime设置回收掉线的Socket时间间隔。

  3. Start启动方法。启动方法允许用户使用单线程运行和多线程运行,也可以在启动的同时注册自己的业务对象。线程数量由通讯服务类由运行服务的物理机CPU核心数决定,线程数量最大为CPU*2-1.不允许用户自行开辟线程。

  4. RegisterBussiness注册业务对象方法。通过RegisterBussiness方法注册用户通过实现业务接口类完成自己的业务逻辑。

    连接器类(TConnector):连接器类是通讯服务程序的核心,客户端与服务端连接成功后,会产生一个连接会话通道,该通道我们称为连接器,客户通过连接器发送数据到服务端,服务端通过连接器发送数据到客户端。每个连接器有一个唯一标识符ConnectorId,通过客户端唯一标识符ClientId建立与客户端的关联。用户可以通过查询连接器ConnectorId或者ClientId获取指定的连接器。连接器的主要作用就是读取数据或者下发数据到客户端,读取到的数据通过业务接口传递给业务处理类,由业务处理类处理数据。

    连接器管理类:连接器管理类提供保存连接器的容器,作为通讯内部管理类,提供连接器插入到容器、关闭连接器、删除连接器、更改连接器客户端ID和连接器工作参数。

    业务接口类:为用户提供业务处理模板。用户通过实行业务接口实现自己的业务逻辑。

    流程描述:

     

2.3. 详细设计

曾经用Delphi写过windows完成端口模型的通讯代码,而C++,尚未入门,临时抱佛脚采用QT编辑器尝试编写本案例详细设计和具体实现,很多命名规则还保留有一些记忆中的Delphi风格。为方便专业级别的C++程序员审阅本案例,也因本人不喜欢阅读那些带下划线的代码,本详细设计命名规则解释如下:

  1. 所有的类名均用大写的T字母开头。

  2. public类成员变量统一由大写的字母开头。成员变量由两个单词组成的,每个单词的首字母均采用大写。

  3. Protect或者Private成员变量m+单词首字母命名。

  4. Public方法名,只有一个单词的由单词的第一个字母大写,其他字母小写。 由2个单词组成的,每个单词第一个字母采用大写,其他用小写。

  5. Protect或者private方法,均采用首个单词全部小写,其他单词的第一个字母大写。

  6. 除非不得已,本设计常量定义尽量采用const,不使用宏定义。

    通讯服务类、连接器类、连接器管理类、业务逻辑接口,业务逻辑示例TDefeaultBussiness类详细设计及各对象之间的关系如下图所示。

         

2.3.1. 通讯服务器类(TTcpserver

一、通讯服务器工作流程:

  1. 使用TTcpServer::TTcpServer()构造器生成一个TTcpserver对象,如TTcpserver  tcpserver; 或者使用带ip地址和端口号参数的构造器TTcpserver::TTcpServer(string ipAddr,int port)生成一个TTcpServer对象。

  2. 如果还没设置监听的IP地址和端口的,调用SetIpAddress设置监听IP地址和端口。

  3. 调用 RegisterBussiness方法绑定用户自己实现的业务逻辑对象。

  4. 调用SetRecycleSocketTime方法设置回收断线的客户端连接,该步骤可选,如果用户不调用该方法,则默认10分钟回收一次。

  5. 调用Start方法启动服务,参数为True时将根据运行的物理服务器CPU核数产生2*CPU核数-1的线程数量运行通讯服务。

  1. 功能描述:

  1. waitAccept方法:使用异步方式等待远程客户端连接,当有连接请求时。如果连接成功,调用连接成功回调函数来保存连接和投递异步读等待。

  2. acceptHandle方法:是waitAccept方法的回调函数,连接成功后该方法被调用,保存连接器和投递异步读事件。 如果有异常,则把异常写到异常日志中。

  3. Start方法:启动服务。首先调用waitAccept等待连接,然后调用连接器管理对象中的OpenTimers方法启动连接器回收掉线的连接器,最后调用采用线程方式启动mIoServer.run。

     

2.3.2. 连接器类

功能描述:

  1. DoRead:投递异步读事件等待数据接收,如果读到客户端关闭的错误代码,则关闭连接。

  2. ReadHandle:异步读事件回调函数,当读取到数据后,通过业务接口把数据传递到业务处理对象。再次调用DoRead投递读事件

  3. DoWrite:投递异步写事件,由于什么时候在连接器上面进行写操作是由客户端或者应用协议决定的,投递写事件由业务逻辑接口调用。

  4. writeHandle:异步写回调函数,通过该回调函数将写结果通知给业务层。

2.3.3. 连接器管理类

功能描述:

  1. AddConnector方法:为连接器生成连接器ID,并把连接器对象保存到连接器容器中。工作流程:

    首先中连接器ID回收站中获取可以利用的ID,如果没有,则通过增长方式建立一个ID。

  2. 其次调用容器的插入方法保存连接器对象。

  3. GetSocket方法:通过连接器ID或者客户端ID获取连接器。

  4. UpdataConnector方法:当客户端注册后,更新连接器的ClientId。由业务接口调用。

  5. checkConnection方法:定时检查连接器容器中是否有掉线的连接器,并将掉线的连接器中删除掉线的连接器。

   源代码:


/***********************************************

* 撰写时间:2016年8月12日

*C++ 等级:初级

*作者:

*/

#ifndef TCPSERVER_H

#define TCPSERVER_H

#include <boost/asio.hpp>

#include <boost/bind.hpp>

#include <boost/thread.hpp>

#include "connector.h"

#include "connectormanager.h"

#include "userbusiness.h"

#include <string>

using namespacestd;

class TTcpServer

{

   public:

    //提供默认的构造函数

    TTcpServer();

    //提供通过IP和端口构造服务类的构造函数

    TTcpServer(conststringipAddress,shortport);

   //~TTcpServer(){}

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Boost.Asio是一个开源的跨平台网络编程库,它可以用于构建高效的异步I/O应用程序。以下是一些关于Boost.Asio的学习资源: 1. Boost.Asio官方文档:Boost.Asio的官方文档提供了详细的介绍和使用指南,包括教程、参考文档和示例代码。文档链接:https://www.boost.org/doc/libs/1_77_0/doc/html/boost_asio.html。 2. Boost.Asio学习指南:这是一篇由Boost.Asio的核心开发者编写的学习指南,它介绍了Boost.Asio的基本概念和使用方法,并提供了一些示例代码。指南链接:https://think-async.com/Asio/asio-1.18.1/doc/asio/overview/core.html。 3. Boost.Asio教程:这是一系列由Boost.Asio社区成员编写的教程,涵盖了从基础到高级的内容。教程链接:https://github.com/chriskohlhoff/asio/tree/master/asio/doc/tutorial。 4. Boost.Asio实战:这是一本关于使用Boost.Asio构建网络应用的书籍,它详细介绍了Boost.Asio的使用方法和实践经验,并提供了大量示例代码。书籍链接:https://www.oreilly.com/library/view/boostasio-c/9781785283079/。 希望这些资源能够帮助您学习和掌握Boost.Asio。 ### 回答2: boost.asio是一个基于C++的网络编程库,为开发人员提供了一套强大而灵活的工具来实现异步网络通信。 该库的教程涵盖了boost.asio的核心概念、基本用法和高级功能。首先,教程介绍了异步编程的概念,以及为什么应该使用异步编程来处理网络通信。然后,它讲解了boost.asio的核心组件,例如IoService、Socket和Buffer,以及如何使用它们进行网络连接和数据传输。 教程还会指导开发人员如何使用boost.asio处理不同类型的网络协议,例如TCP/IP和UDP。开发人员将学习如何创建服务器和客户端,并使用boost.asio异步操作来处理连接和数据传输。教程还会介绍一些常见的网络编程任务,例如并发服务器和多线程编程,以及如何使用boost.asio来解决这些问题。 除了基本内容外,教程还涵盖了boost.asio的高级功能,例如SSL加密、定时器和信号处理。开发人员将学习如何使用SSL加密来保护网络通信,以及如何使用定时器来处理超时和延迟。此外,教程还会介绍如何使用信号处理来处理中断和异常情况。 总的来说,boost.asio教程为开发人员提供了一个全面的参考资料,帮助他们掌握这个强大的网络编程库。无论是初学者还是有经验的开发人员,都可以从中学习到如何使用boost.asio来构建高效可靠的网络应用程序。 ### 回答3: boost.asio是一个用于异步I/O操作的C++库。它提供了一个面向对象的接口,可以用于处理网络编程、文件I/O和串口通信等操作。boost.asio设计目标是高效和可扩展性。 boost.asio教程是一个系统介绍boost.asio库的学习材料。该教程通常包含以下内容: 1. 引言:介绍boost.asio库的作用和特性。解释为什么选择boost.asio而不是其他库。 2. 环境配置:指导读者如何安装和配置boost.asio库。包括下载和安装boost库、配置编译器和连接器等步骤。 3. 基本概念:介绍boost.asio库的基本概念和术语。例如,异步操作、回调函数、handler等。 4. 网络编程:教授如何使用boost.asio库进行网络编程。包括创建Socket对象、建立连接、发送和接收数据等操作。 5. 文件I/O:介绍如何使用boost.asio库进行文件读写操作。教授如何打开文件、读取和写入数据等。 6. 串口通信:介绍如何使用boost.asio库进行串口通信。教授如何打开串口、发送和接收数据等。 7. 高级主题:介绍一些高级主题,例如多线程编程、定时器、SSL加密等。这些主题可以帮助读者更深入地理解和使用boost.asio库。 通过学习boost.asio教程,读者可以学会使用boost.asio库进行异步I/O操作。他们可以编写高性能的网络应用程序、文件处理程序和串口通信程序。同时,他们还能够了解到一些高级主题,从而扩展他们的技能和知识。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值