ACE(ADAPTWE Communication Environment)是用于构建高性能网络化应用和下一代中间件的开放源码工具包,已在世界各地的许多项目中得到了广泛应用。本书是《c++网络编程》(卷2)的前篇,由ACE的创始人Douglas C. Schmidt及主要开发者之一StephenD.Huston撰写而成,其内容涵盖了ACE中的各主要框架的基础概念、模式及使用规则。本书将向你摧述这些框架的设计,以及它们可怎样帮助你克服较低级的本地操作系统API与较高级的分布式计算中间件的各种局限,高效地开发出高质量、可移植的C++网络化应用。本书是继受到了高度赞誉的POSA2(Pattem- OrientedSottwareArchitecture:Patterns for Concurrent and Networked Objects)之后,Douglas C.Schmidt撰写的又一著作,通过学习本书,你将能更深入地了解和掌握适用于网络化应用开发的各种设计模式。
第0章 设计课题、中间件方案、ACE\r\n 0.1 网络应用面临的挑战\r\n 0.2 网络应用的设计空间\r\n 0.3 面向对象中间件方案\r\n 0.4 ACE工具包概览\r\n 0.5 示例:一个网络日志服务程序\r\n 0.6 小结\r\n第1篇 面向对象网络编程\r\n 第1章 通信设计空间\r\n 1.1 无连接协议与面向连接协议\r\n 1.2 同步及异步消息交换\r\n 1.3 消息传递与共享内存\r\n 1.4 小结\r\n 第2章 Socket API概述\r\n 2.1 操作系统IPC机制概述\r\n 2.2 Socket API\r\n 2.3 Socket API的局限性\r\n 2.4 小结\r\n 第3章 ACE Socket Wrapper Facade\r\n 3.1 概述\r\n 3.2 ACE_Addr类和ACE_INET Addr类\r\n 3.3 ACE_IPC_SAP类\r\n 3.4 ACE_SOCK类\r\n 3.5 ACE_SOCK_Connector类\r\n 3.6 ACE_SOCK_10类和ACE_SOCK_Stream类\r\n 3.7 ACE_SOCK_Acceptor类\r\n 3.8 小结\r\n 第4章 网络日志服务程序的实现\r\n 4.1 概述\r\n 4.2 ACE_Message_Block类\r\n 4.3 ACE_InputCDR类和ACE_OutputCDR类\r\n 4.4 日志服务器的初始版本\r\n 4.5 客户程序\r\n 4.6 小结\r\n第2篇 并发式面向对象网络编程 \r\n 第5章 并发设计空间\r\n 5.1 循环、并发及反应式服务器\r\n 5.2 进程与线程\r\n 5.3 进程/线程创建策略\r\n 5.4 用户、核心及混合线程模型\r\n 5.5 分时及实时调度级别\r\n 5.6 “基于任务”与“基于消息”的体系\r\n 5.7 小结\r\n 第6章 操作系统并发机制概述\r\n 6.1 同步事件多路分离\r\n 6.2 多进程机制\r\n 6.3 多线程机制\r\n 6.4 同步机制\r\n 6.5 OS并发机制的局限性\r\n 6.6 小结\r\n 第7章 ACE同步事件多路分离wrapper Facade\r\n 7.1 概述\r\n 7.2 ACE Hanolle_Set类\r\n 7.3 ACE_Handle_Set_Iterator类\r\n 7.4 ACE::select()方法\r\n 7.5 小结\r\n 第8章 ACE进程Wrapper Facade\r\n 8.1 概述\r\n 8.2 ACE_Process类\r\n 8.3 ACE_Process_Options类\r\n 8.4 ACE_Process_Manager类\r\n 8.5 小结\r\n 第9章 ACE线程Wrapper Facade\r\n 9.1 概述\r\n 9.2 ACE_Thread_Manager类\r\n 9.3 ACE_Sched_Params类\r\n 9.4 ACE_TSS类\r\n 9.5 小结\r\n 第10章 ACE同步Wrapper Facade\r\n 10.1 概述\r\n 10.2 ACE_Guard类\r\n 10.3 ACE互斥体类\r\n 10.4 ACE Readers/Writer Lock类\r\n 10.5 ACE信号量类\r\n 10.6 ACE条件变量类\r\n 10.7 小结\r\n附录A ACE C++Wrapper Facade的设计原则\r\n A.1 概述\r\n A.2 通过Wrapper Facade增强类型安全性\r\n A.3 简化常见情形\r\n A.4 通过继承结构提高设计的清晰性和可扩充性\r\n A.5 尽可能地隐藏平台间的差异\r\n A.6 针对效率实施优化\r\n A.7 小结\r\n附录B ACE的过去、现在和将来\r\n B.1 ACE的演变\r\n B.2 未来之路\r\n B.3 结束语\r\n术语表\r\n参考文献\r\n索引
为本书作序之时,我正在欧洲畅游,这多亏了欧洲完善的公共交通设施。作为一个美国人,我不禁被这里的基础设施所倾倒。无论在什么地方,只要我一下飞机,就可以方便地找到火车或巴士,享受快速、整洁、安全、准时的服务——或许,更重要的是:将我直接送到目的地。此外,离站和到站的通告用多种语言表示,各种标志和指示也易于理解,即使是我这样一个不懂当地语言的人,也没有感到丝毫的不便。
我生活、工作在Boston,和大多数美国人一样,我几乎完全靠自己的汽车辗转于各个场所。除了偶尔光顾一下Boston的地铁系统之外,我总是自己开车外出。因为公共交通设施有太多的限制,它很难将我送到目的地。数百万Boston居民以及其他地方的人们也都处于同样的困境,可见,我们的公路系统已经过时,远不能承受今天的交通量。我知道,如果仔细算一算自己一生中因为塞车而浪费的时间,一定会吓一跳。
有趣的是,网络计算系统(networked computing system)和交通系统之间有某些相似之处,其中最显著的一点是:二者的成功都离不开“可伸缩(scalable)”的基础设施。所谓可伸缩的交通系统,不只包括那些显而易见的设施,如火车和铁轨、飞机和机场,还需要有调度、路线选择、维修、检票、监控,而这一切还要能够随着物理上的交通系统的变化而伸缩、变化。类似地,网络计算不仅需要主机和网络——物理上的计算和通信基础设施——还需要软件上的调度、路由选择、分发、配置、转译、验证、授权和监控——只有这样,网络系统才能根据需要调节、变化。
说到基础设施,有这样一个具有讽刺意味的事实:建设好基础设施,这本身已经非常之难;但更难的是,只有让用户越感觉不到它的存在,人们才会认为它越成功。举个例子:瑞士境内的阿尔卑斯山脉地势崎岖,但是,为数不多的设计师、工程人员和建筑工人却凭借他们的技能,为无数的瑞士居民提供了有效的交通系统,从而给他们的日常生活带来了便利。事实上,这套系统如此可靠易用,以至于你很快将它的存在当成是理所当然之事,它因此变得对你透明了。譬如,当你踏上瑞士的铁路之旅时,你的心思只会放在该从哪一个地方到达另一个地方上,而不会关心是什么样的交通工具将你载到那儿。除非你是个游客,否则,你大概不会注意到你正在穿越一个历经数年设计、修建的隧道,也不会注意到火车正攀行在如此陡峭的斜坡上,更不会注意到铁路上还安装了齿轨,以帮助列车爬行。铁轨设施完美地承担了它的职能,所以,你甚至没有注意到它的存在。
本书针对网络计算系统,探讨了一种基础设施软件(infrastructure software),通常称为中间件(middleware)。之所以称为“中间件”,是因为它就像“沙漏的腰(waist in the hourglass)”,位于操作系统和网络之上、应用程序之下。中间件具有多种形态(shapes)、规模(sizes)和能力(capabilities):从J2EE应用服务器、异步消息处理系统、CORBA ORB,到小型嵌入式系统中的Socket监控软件。中间件必须支持日益繁多的应用程序、操作系统、网络协议、编程语言和数据格式。如果没有中间件,要想应对网络计算系统中日益增长的多样性(diversity)和异种性(heterogeneity),将十分麻烦,而且容易出错且代价昂贵。
中间件种类繁多,要解决的问题也各式各样,但在解决各种复杂难题时,不同类型的中间件往往采用相同的模式(patterns)和共同的抽象(abstractions)。例如,如果去窥探一个具有可伸缩性和灵活性的应用程序服务器、消息系统或CORBA ORB的内部,就会发现,它们采用了类似的技术来完成诸如连接管理、并发、同步、事件多路分离、事件处理程序分发、错误记录、监控等任务。如同瑞士铁路系统的用户数量远远大于设计和建造铁路的工程人员的数量那样,一套成功的中间件的用户数量也远远大于设计和构造中间件的开发人员的数量。如果要设计、构造或使用中间件,那么,只有熟悉、理解和运用这些常见模式和抽象,才会获得成功。
虽然很多人都知道,中间件必须具有可伸缩性和灵活性,但很少有人能够高效地提供这种中间件。然而,Doug Schmidt和Steve Huston在本书介绍的ADAPTIVE通信环境(ACE)中却做到了这一点。ACE是一套应用广泛的C++工具包,它汇集了很多常用的模式和抽象,这些模式和抽象在各种极为成功的中间件和网络程序中都有广泛的应用。ACE已经成为许多网络计算系统的基础:从实时的航空电子应用到CORBA ORB,以及对主机“端对端(peer-to-peer)”通信的支持。
和其他所有优秀的中间件一样,ACE也将异种环境下各式各样的复杂性隐藏在底层;和其他众多基础设施中间件不同的是:ACE能够在程序
Stephen D.Huston,Riverace Corporation总裁、CEO,为ACE用户提供技术支持和咨询服务。Steve具有5年多ACE使用经验和20多年软件开发经验,主要从事多种软硬件环境下的网络协议和C++网络应用程序的开发。
过去10年,并发式“面向对象”网络编程(concurrent object-oriented network programming)已经成为一种有效的应用软件开发范式(paradigm)。在这些应用程序中,相互协作的对象可以:
1. 在一个进程或计算机中相互关联;
2. 分布在一组通过网络(如嵌入式互连系统、局域网(LAN)、企业内部网、互联网)相连的计算机中。
如果对象是分布(distributed)存在的,那么,组成这些对象的各种实体(entity)之间就要能够有效地通信和协调。而且,当应用程序在其生命周期内发生变化时,也必须始终这样。对象的布局、现有网络设施、平台并发机制的选择都允许有一定程度的自由,这种自由带来了强大的功能,同时也带来了挑战。
如果设计合理的话,并发式“面向对象”网络编程将提供强大的功能,从而大大提高应用程序的灵活性。例如,根据项目的需求和现有资源,可以使用:
实时(real-time)、嵌入式(embedded)或手持(handheld)式系统;
个人或膝上型电脑;
各式各样、不同规模的UNIX或Linux系统;
“大型”主机甚至超级计算机。
然而,当你在多个操作系统(OS)平台上开发和移植网络应用程序时,将面临错综复杂的挑战。这些复杂性的表现形式各异:网络协议不兼容,在不同软、硬件平台上具有不同API和
语义的组件库,OS本身的(native)进程间通信(IPC)机制和并发机制的局限性造成的“偶发复杂性(accidental complexity)”。为减小这些问题的影响,ADAPTIVE Communication Environment(ACE)提供了一套“面向对象”工具包。此工具包可运行在大量硬件和OS平台上,包括Win32和UNIX的大多数版本,以及很多实时及嵌入式操作系统。
可能有人告诉过你:一些“事实上”或“官方”的OS标准(如POSIX、UNIX98或Win32),是所有程序员的保护伞,它们可以让你的应用程序免受“可移植性”难题的困扰。不幸的是,有这样一句格言:“标准的最大好处是,它们提供了大量的选择”[Tan96]。这一格言在今天比在10年前更适用。今天,数十种不同的OS平台正应用于商业、学校和政府项目中,每一个新版本和变体的出现,都会使这个数列增加。
过去20年里,我们开发过很多“跨平台”的并发式网络系统。因而,我们可以明确地告诉你:在不同的时期,OS供应商使用的标准也往往不同。何况,标准也是不断变化和发展的。你很可能工作在多个平台上,而这些平台是在不同的时期、以不同的方式去实现标准的。因而,直接针对OS API编程会导致以下两个问题。
1. 容易出错。因为用C写成的、OS本身具有的API一般都缺乏类型安全(type safe)、可移植(portable)、可重入(reentrant)、可扩充(extensible)的系统函数接口和函数库。例如,在广泛使用的Socket API(将在第2章讲述)中,通信端点是通过“弱类型化(weakly typed)”的“整数”或“指针”型I/O句柄(handle)来标识的,这无疑增加了程序运行时产生微妙错误的可能性。
2. 助长“不恰当”的设计技术的运用。因为很多用OS API写成的网络应用程序都是基于“算法”设计(algorithm design),而不是“面向对象”设计(object-oriented design)的。算法设计需要根据特定的功能需求来分解程序的结构,而功能需求并非一成不变——随着时间的变化,它很可能也会发生变化。因而,这种设计范式(paradigm)导致的软件结构将无法扩充,也无法根据不断变化的应用需求作出快速响应[Boo94]。
在这个经济动荡、缺乏管制、全球激烈竞争的年代,如果完全通过原始的(native)OS API和算法设计技术来开发应用程序,其昂贵的开销和时间上的浪费将让人无法忍受。
如果你多年来一直从事网络软件系统的开发,或许早已将其中的一些问题视作家常便饭,但是,你还有更好的选择!在本书中,我们将向你介绍,C++和ACE如何为你提供“面向对象”能力,从而让你尽可能地避开很多陷阱和避免犯错误,同时还不失对标准——甚至某些“和平台相关”的特性——的支持。随着时间的推移,“面向对象”设计体现出的稳定性将远胜于“算法”设计。因而,在开发多种类型的网络应用程序时,应该优先选用“面向对象”设计。
不必惊讶,这些灵活性也需要代价:可能需要学习一些新的概念、方法、模式(pattern)、工具和开发技术。根据个人经验的不同,你的学习曲线可能是平坦的,也有可能在一开始就显得很陡峭。但重要的是,“面向对象”设计范式(paradigm)为你提供了一套成熟的技术,可以让你应对网络应用程序开发中的很多挑战。本书给出了一系列具体的示例,向你展示如何运用“面向对象”技术开发和应用ACE工具包中的类。你可以运用相同的技术和ACE类来简化自己的应用程序。
目标读者
本书奉献给“一线”程序员或高年级学生,因为当运用C++和“面向对象”设计技术进行并发网络编程时,他们需要了解其中的战略、战术。我们将讲述重要的设计空间(dimension)、模式和原则——要想快速方便地开发灵活高效的并发式网络程序,就需要了解它们。我们提供了大量的C++代码范例,让你强化对设计概念的理解,还具体演示如何尽快使用ACE中的核心类。我们还将你带到“幕后”,让你理解ACE工具包中的IPC和并发机制是如何设计的,以及为什么要那样设计。这些内容将帮助你增强设计技能,在“面向对象”网络程序中更高效地运用C++和模式。
本书并非是讲述“面向对象”开发、模式、UML、C++、系统程序设计或网络技术的详尽教程。所以我们假设,对于以下主题,本书读者应该有一定程度的了解。
面向对象设计及编程技术。例如,框架(framework)[Joh97, FJS99b, FJS99a]、模式(pattern)[GHJV95, BMR+96, SSRB00]、模块化(modularity)[Mey97]、信息隐藏(Information hiding)[Par72]、建模(modeling)[Boo94]。
面向对象表示法及处理方式。例如,Unified Modeling Language(UML,统一建模语言)[RJB98]、eXtreme Programming(极限编程)[Bec00]、Rational Unified Process(RUP,Rational统一过程)[JBR99]。
C++语言的基本特性。例如,类(class)、继承(inheritance)、动态绑定(dynamic biding)、参数化类型(parameterized type)[Bja00]。
核心系统编程机制。例如事件多路分离、进程和线程管理、虚拟内存、UNIX[Ste98, Ste99, Ste92, Lew95, KSS96, But97]和Win32[Ric97, Sol98, JO99]平台上都存在的IPC机制和API。
网络术语和概念。例如,TCP/IP[Ste93]、远程操作请求[Obj01]、客户/服务器架构[CS92]。
我们鼓励你广泛使用参考资料,针对想深入学习的主题去追根溯源。
本书也不是一部针对ACE程序员的使用手册,也就是说,我们没有对ACE中的每一个类(class)、每一个方法(method)进行说明。如果想达到那样详细的程度,可以查看完整的ACE在线文档,这些文档用Doxygen [Dim01]生成,由http://ace.ece.uci.edu/Doxygen和http://www.riverace.com/docs提供。相反,本书讲述的重点是:
设计成功的面向对象的网络应用程序和中间件需要了解的重要概念、模式和C++特性;
最常用的ACE TCP/IP及并发式wrapper facade类背后的设计动机及其基本应用。
结构和内容
本书讲述的内容是:如何用C++和中间件来解决网络应用程序开发中相关的重要课题。首先回顾主流OS平台本身具有的核心OS机制,并阐释如何在ACE中运用C++和模式,将这些机制封装到类库(class library)wrapper facade之中,从而提高应用程序的可移植性和健壮性。本书用到的主要例子是一个网络日志服务程序,其功能是:通过TCP/IP,将日志记录从客户程序传输到一个日志服务器。我们将这个服务程序作为贯穿全书的示例,从而具体演示:
C++和ACE如何有助于实现高效、可预测和可伸缩的网络应用程序;
开发并发式“面向对象”网络程序时,在设计和实现上要考虑到哪些因素和方案。
本书分为11章,其主要内容简介如下。
简介——第0章是有关C++网络编程的基本介绍。首先,勾勒出问题空间 (problem space),提出应用程序运行在单进程、单线程的情况下可能面临的课题。然后,引入中间件层(middleware layer)的分类(taxonomy)概念,并讲述如何运用主机设施中间件和ACE工具包来解决常见的网络编程问题。
第1篇——第1~4章概要
无封面