<<C++网络编程 卷2 基于ACE和框架的系统化复用>>
第1章 用于网络编程的面向对象框架
1.1 面向对象框架综述:机会主义复用:把有用的代码复制到自己的程序中。系统化复用:创建并应用多用途的软件架构、模式、框架和组件。
1.2 比较各种软件开发和复用技术:
1.2.1 比较框架和类库:框架和类库在实践的应用中时互补的技术。框架给程序提供基础性的结构。但框架聚焦于特定领域,不能满足最广泛的应用需求,因此在框架的应用中结合类库。
1.2.2 比较框架和组件:框架和组件之间的关系是高度协作的,谁也不从属于谁。
1.2.3 比较框架和模式:
1.2.4 比较框架和模型集成式计算:
1.3 将框架应用到网络编程:
1.4 周游ACE框架:
1.5 实例:网络化日志服务
第2章 服务和配置设计维度
2.1 服务和服务器设计维度:
2.1.1 短持续时间服务 VS 长持续时间服务:短持续时间服务是执行时间短的,且常常是固定的,比如时间计算服务。长持续时间服务的运行时间更长,且常常是变长的,比如FTP等。
2.1.2 内部服务 VS 外部服务:内部服务在于接受请求的服务器相同的地址空间执行,因此内部服务会破坏整个服务器的共享变量,从而影响服务器健壮性。外部服务执行在不同的进程地址空间中,互相不受影响,由于需要IPC,因此性能会有损害,一般重要的服务都放在外部服务中。
2.1.3 有状态服务 VS 无状态服务:有状态服务在服务器中缓存特定的信息,比如会话状态、认证密钥、标识号、IO句柄等,以降低通讯的计算开销。无状态服务不在服务中保存易变的状态。
2.1.4 分层式/模块化服务 VS 整体式服务:分层式/模块化服务可被分解进一系列分开的、层次相关的任务中。整体式服务没有进行层次划分的多个紧密耦合的功能块。整体式服务适用于原型开发,不利于扩展。
2.1.5 单服务服务器 VS 多服务服务器:单服务服务器只提供单一服务。缺点:消耗过多OS资源,比如文件描述符、虚拟内存等;编写冗余初始化代码;安装新的服务实现时必须关闭、重启进程;多服务服务器将多个单服务服务器集成到同一进程从而改善单服务服务器的局限。优点刚好是单服务服务器的缺点。
2.1.6 一次性服务器 VS 持续性服务器:一次性服务器是随需派生。持续性服务器是持续运行中。
2.2 配置设计维度:
2.2.1 静态命名 VS 动态命名:静态命名,在编译时或者静态链接是把服务的名字与存在的代码联系在一起。动态命名,推迟了把服务名字和代码的关联。
2.2.2 静态链接 VS 动态链接:静态链接,通过在编译时或静态链接时将其所有的文件对象绑定在一起来创建完整的可执行程序。动态链接,在程序被初次调用是加载对象文件到进程的地址空间,或是进行卸载。
2.2.3 静态配置 VS 动态配置:
2.3 总结:服务器设计维度影响应用程序构造、开发或实例化的方式。配置维度影响用户或管理员在网络化服务发布或部署以后,改变运行时安排和配置的能力。
第3章 ACE Reactor框架
3.1 综述:ACE Reactor框架(由ACE_Time_Value、ACE_Event_Handler、ACE_Timer_Queue、ACE_Reactor类构成)。
主要功能:
(1).检测来自各种事件源的事件发生。
(2).将事件多路分离给其预先登记的事件处理器。
(3).分派给处理器所定义的挂钩方法,从而以一种应用定义的方式处理这些事件。
优点:
(1).广泛的可移植性。
(2).使事件检测、多路分离、以及分派自动化。
(3).透明的可扩展性。
(4).增加复用并使错误减至最少。
(5).高效的事件多路分离。
3.2 ACE_Time_Value类:该类提供如下功能:
(1).提供一种标准化的时间表示,可以跨OS使用。
(2).各种平台的时间表示之间相互转换,比如UNIX上的timespec_t、Windows上的FILETIME。
(3).使用运算符重载来简化基于时间的比较,这样可以将C++标准的语法用于时间的比较和算术运算。
(4).它的构造器和方法通过将timeval中的域转换为规范的格式,对时间量进行规范化,从而确保了在ACE_Time_Value类实例之间进行精确的比较。
(5).可以表示一段持续时间,比如5秒又2000微秒,或者绝对的日期时间比如2012-10-19 20:12:25 。
3.3 ACE_Event_Handler类:该类提供如下功能:
(1).定义输入事件、输出事件、异常时间、定时器事件以及信号事件。
(2).挂钩方法允许应用以许多方式扩展事件处理器子类,而不必改变框架。
(3).对面向对象回调的使用简化了“数据”与“对这些数据进行操作的挂钩方法”的关联。
(4).它对对象的使用还使“一个事件源(或成组的事件源)”与“事件源所关联的数据(比如网络会话)”的绑定得以自动化。
(5).将不在需要的事件处理器的销毁集中在一起。
(6).它持有一个指针,指向管理它的ACE_Reactor,从而使事件处理器对其事件登记和解除登记的正确管理变的很简单。
3.4 ACE定时器队列类:
(1).允许应用调度事件处理器,handle_timeout()挂钩方法将在未来,在调用者指定的时间被高效而可伸缩的分派--或是一次性的或是周期性的。
(2).允许取消与特定事件处理器相关联的某个定时器,或是与某个事件处理器相关联的所有定时器。
(3).允许应用配置定时器队列的事件源。
3.5 ACE_Reactor类:该类提供如下功能:
(1).使反应式应用中的事件循环处理得以集中在一起。
(2).通过事件多路分离器(select, epoll)来检测事件,这些分离器由OS提供,反应器实现使用了它们。
(3).在事件多路分离器指示有指定时间发生时,将事件多路分离给事件处理器。
(4).分派已登记的事件处理器上的适当的挂钩方法来执行应用所定义的处理,以对事件作出响应。
(5).确保任何线程都可以改变反应器的事件集,或是排队对事件处理器的回调,并期望反应器会迅速的对请求作出处理。
第4章 ACE_Reactor实现:
4.1 综述:ACE_Select_Reactor、ACE_TP_Reactor、ACE_WFMO_Reactor。
4.2 ACE_Select_Reactor类:提供如下功能:
(1).支持重入的反应器调用。
(2).可被配置为可同步化的或非同步化的,在线程安全性和降低开销之间进行折中。
(3).再次调用select()之前,分派其句柄集中的所有活动句柄,从而保证了公正性。
4.3 ACE_TP_Reactor类:该类实现了Leader/Followers模型。提供如下功能:
(1).能让一“池”的线程调用handle_event()函数。这样通过并发的处理多个句柄上的事件,可以改善可伸缩性。
(2).能防止多个I/O事件在不同的线程中被同时分派给同一个处理器。这一约束保持了ACE_Select_Reactor的IO分派行为,减少为处理器的IO处理增加同步锁的需要。
(3).某个线程从select()那里获取了一组活动句柄后,其他反应器线程会从该句柄集那里进行分派,而不是再次调用select()。
4.4 ACE_WFMO_Reactor类:提供如下功能:
(1).能让一“池”的线程调用handle_event()函数。这一机制比ACE_TP_Reactor的更为强大。在ACE_WFMO_Reactor中所有的事件处理线程都可以并发的分派事件,而不用以领导者/跟随者的方式轮流工作。
(2).允许应用等待socket IO事件和调度定时器。
(3).每个对handle_events()的调用会等待某个句柄变为活动的,从该句柄开始,它在返回之前从头到尾迭代取得其他所有的活动句柄。这一设计可防止一个活动句柄饿死句柄集数组中排列在其后面的句柄。
(4).使用ACE_Msg_WFMO_Reactor子类,应用可以处理上面所有的事件和窗口消息。
第5章 ACE Service Configurator框架
5.1 综述:ACE Service Configurator框架主要由下面几个类构成ACE_Service_Object、ACE_Service_Repository、ACE_Service_Repository_Iterator、ACE_Service_Config。
5.2 ACE_Service_Object类:该类实现如下功能:
(1).提供了初始化服务和关闭服务的挂钩方法。例如:分配资源和清理资源。
(2).提供了暂时挂起服务执行和恢复服务执行的挂钩方法。
(3).提供了一个挂钩方法来报告关键的服务信息。
5.3 ACE_Service_Repository类:该类实现了Manager模式,控制框架配置的服务对象的声明周期,以及对他们的访问。该类实现如下功能:
(1).追踪被配置进某个应用的所有服务实现,并维护各个服务的状态。比如:服务是活动的还是挂起的。
(2).提供了插入、管理和移除服务的机制。
(3).提供了终止所有服务的机制,终止的顺序与初始化过程相反。
(4).可以通过服务名称来定位某个服务。
5.4 ACE_Service_Config类:该类实现了ACE Service Configurator框架中的其他类,并对管理应用中的各个服务所必须的活动进行协调。该类提供如下功能:
(1).它解释这样一种脚本语言,该语言允许应用或管理员给ACE Service Configurator提供命令---叫做指令---以在运行时定位和初始化服务的实现,以及组件在初始化以后挂机、恢复、重新初始化或关闭。
(2).它可以管理“位于应用中的服务(所谓静态服务)以及必须从分离的共享库(DLL)中动态链接的服务(所谓动态服务)。
(3).在运行时进行服务重配置。(比如:收到某个信号后重新读取配置表)。
第6章 ACE Task框架:
6.1 综述:该框架提供了强大而可扩展的面向对象并发能力,比如在对象的上下文中派生线程,以及在执行在不同线程的对象之间传送消息和对消息进行排队。该框架可被用于实现一些关键的并发模式:
(1).Active Object模式:它解除了“调用某个方法的线程”和“执行该方法的线程”之间的耦合。该模式增强了并发性,并简化了对“执行在一个或多个线程的上下文中的对象”的同步访问。
(2).Half Sync/ Half Async模式:解除了并发系统中异步与同步处理的耦合,从而能够简化编程,而又不会带来严重的性能下降。该模式引入三个层次:一层用于异步(或反应式)处理;一层用于同步处理;还有一层排队层负责协调异步层和同步层之间的通信。
6.2 ACE_Message_Queue类:ACE_Message_Queue是一款轻量级的线程内消息排队机制。功能如下:
(1).允许程序员将消息(ACE_Message_Block)放入队列的前部、后部。或者根据消息的优先级放置在合理的位置。消息可从队列的前部或后部取。
(2).它使用ACE_Message_Block来提供一种高效的消息缓存机制,使动态内存分配和内存复制最小化。
(3).它即可为多线程化配置,也可以为单线程化配置进行实例化。并允许程序员在不需要对队列进行并发访问时,取消严格的同步来换取更低的开销。
(4).在多线程化的配置中,它支持可配置的流控制,可防止快速的生产者线程耗尽较慢的消息消费者线程的处理和内存资源。
(5).允许对出队和入队设定超时,以防止无限期的等待。
(6).可与ACE_Reactor框架的事件处理机制集成在一起。
(7).提供了可定制策略的分配器,这样,消息所需的内存可从多个来源获取,比如共享内存、堆内存、静态内存或者线程特有的内存等。
6.3 ACE_Task类:ACE_Task类是该框架的基础。功能如下:
(1).使用ACE_Message_Queue的一个实例来使数据和请求与其处理分离。
(2).使用ACE_Thread_Manager类来激活任务,这样任务就会作为主动对象而运行,这个主动对象在一个或多个控制线程中处理其队列中的消息。因为各个线程运行的是一个指定的类方法,所以他们可以访问所有的数据成员。
(3).继承自ACE_Service_Object类,因此它可以进行动态配置。
(4).它是ACE_Event_Handler的后代,所以它的实例还可以在ACE_Reactor框架中充当事件处理器。
(5).它提供了多个虚构方法,应用类可以为任务特有的服务执行和消息处理而重新实现他们。
第7章 ACE Acceptor Connector框架
7.1 综述:Acceptor Connector框架由如下类组成:ACE_Acceptor、ACE_Connector、ACE_Svc_Handler。
7.2 ACE_Svc_Handler类:该类是ACE的同步和反应式数据传输及服务处理机制的基础,提供如下功能:
(1).为同步或反应式网络化应用中的服务初始化和实现提供基础,并充当ACE_Acceptor、ACE_Connector连接工厂的目标。
(2).为服务处理器提供了用于与其对端服务器处理器进行通讯的IPC端点。
(3).因为该类是派生自ACE_Task类,它继承了之间介绍的并发、同步、动态配置和事件处理能力。
(4).使最常见的反应式网络服务活动代码化,比如服务在打开时登记到反应器,在服务解除反应器上的登记时关闭IPC端点。
7.3 ACE_Acceptor类:该类属于工厂类,实现如下功能:
(1).它解除了“被动的建立连接和服务初始化逻辑”与“服务处理器在连接和初始化后的所执行的处理”的耦合。
(2).它提供了一个被动模式的IPC端点,用于侦听和接受对端的连接。
(3).它使“被动的连接IPC端点,创建、激活与其相关联的处理器”所必须的步骤得以自动化。
(4).ACE_Acceptor派生自ACE_Service_Object类,因此它具备了事件处理和配置能力。
7.4 ACE_Connector类:
(1).它解除了“主动的建立连接和服务初始化逻辑”与“服务处理器在连接和初始化后的所执行的处理”的耦合。
(2).它提供了一个主动模式的IPC端点,可以同步地或反应式地主动与对端接收器建立连接。
(3).它使“主动的连接IPC端点,创建、激活与其相关联的处理器”所必须的步骤得以自动化。
(4).ACE_Connector派生自ACE_Service_Object类,因此它具备了事件处理和配置能力。
第8章 ACE Proactor框架
8.1 综述:该框架简化了前摄式IO模型的程序开发,这里描述如下框架类:ACE_Handler、ACE_Asynch_Read_Stream、ACE_Asynch_Write_Stream、ACE_Asynch_Result、ACE_Asynch_Acceptor、ACE_Asynch_Connector、ACE_Service_Handler、ACE_Proactor。该框架负责:
(1).发起异步IO操作。
(2).保存每个操作的参数,并将参数中继给完成处理器。
(3).等待指示这些操作结束的完成事件。
(4).将完成事件多路分离给与其相关联的完成处理器。并且
(5).分派处理器上的挂钩方法,以通过应用定义的方式处理这些事件。
8.2 异步IO工厂:ACE_Asynch_Read_Stream和ACE_Asynch_Write_Stream是两个工厂类,它们使得应用能够发起可移植的异步read()和write()操作。这两个类提供如下功能:
(1).它们可在面向流的IPC机制(如:socket TCP)上发起异步IO操作。
(2).它们将IO句柄、ACE_Handler对象以及ACE_Proactor绑定在一起,以正确而高效的处理IO完成事件。
(3).它们创建将操作的参数从ACE_Proactor携带到它的完成处理器的对象。
(4).它们派生自ACE_Asynch_Operation, 后者提供的接口可用于“初始化对象和请求取消未完成的IO操作”。
8.3 ACE_Handler类:该类是ACE_Proactor框架中所有异步完成处理器的基类,提供如下功能:
(1).它提供了多个挂钩方法来处理ACE中定义的所有异步IO操作完成,包括连接建立和在流上IPC操作。
(2).它提供了定时器到期的挂钩方法。
8.4 前摄式Acceptor-Connector类:
ACE_Asynch_Acceptor类提供如下功能:
(1).它发起异步的被动连接建立。
(2).充当工厂,为每个被动建立的连接创建一个新的处理器。
(3).可以取消先前发出的异步accept操作。
(4).提供了获取对端地址的挂钩方法。
(5).提供了在初始化处理器之前确认对端的方法。
ACE_Asynch_Connector类提供如下功能:
(1).发起异步的主动连接建立。
(2).充当工厂,为每个已经完成的连接创建一个处理器。
(3).可以取消先前发出的异步connect操作。
(4).提供了连接建立时获取对端地址的方法。
(5).提供了在初始化新处理器之前确认对端的方法。
ACE_Service_Handler类提供如下功能:
(1).它为初始化和实现网络化应用服务提供基础,充当ACE_Asynch_Acceptor和ACE_Asynch_Connector工厂的目标。
(2).它接受相连对端的地址,这在Windows系统是很重要的,因为在连接建立后是无法取得对端地址。
(3).该类继承了ACE_Handler,因此它具备处理异步完成事件的能力。
8.5 ACE_Proactor类:该类提供如下功能:
(1).它将前摄式应用中的事件循环处理集中在一起。
(2).它将“定时器到时”分派给与其相关联的ACE_Handler对象。
(3).它将完成事件多路分离给完成处理器,并在完成处理器上分派适当的挂钩方法,由这些方法执行应用定义的处理,以对完成事件进行响应。
(4).它可以解除“执行完成事件的检测、多路分离以及分派的线程”与“发起异步操作的线程”的耦合。
(5).它在“发起IO操作的类”和“平台持有的异步IO实现细节”之间进行协调。
第9章 ACE Stream框架
9.1 综述:主要描述如下两个类:ACE_Module和ACE_Stream类。
9.2 ACE_Module类:该类定义了一个清晰可辨的、由应用定义的功能层。该类提供如下功能:
(1).每个ACE_Module都是双向的、应用定义的处理层,其中含有一对派生自ACE_Task的reader和writer任务。开发者可以轻松的使用ACE_Module来表达分层式设计,从而简化开发、培训和演化。
(2).ACE Services Configuration框架支持ACE_Module对象的动态创建;可以在运行时将ACE_Module配置进ACE_Stream中。因此基于分层式设计的ACE_Module是可扩展的。
(3).包含在ACE_Module中的reader和writer与相邻的ACE_Task是通过挂钩方法传递消息来进行协作的,这促进了松散耦合,并简化了配置。
(4).可以独立的改变和替换组合进ACE_Module中的对象,从而降低维护和改进的开销。
9.3 ACE_Stream类:提供如下功能:
(1).提供多个方法,可以动态的添加、替换和移除ACE_Module对象,从而形成各种流配置。
(2).提供多个方法,可以发送消息给其他的ACE_Stream对象的方法,或者从别的ACE_Stream接受消息的方法。
(3).提供了将两个ACE_Stream流连接在一起的机制。
(4).提供关闭流中所有模块,并等待他们停止的方法。