作者:菩提
网络部分的编程往往是搞得人一个头两个大,各种千奇百怪的问题像土行孙一样从没有防备的地方不断地冒出来,如果碰巧还要还要移植到多平台下――那还不得熬到对影成三人?
高手当然不用愁了:多看看资料了解一下什么VxWorks、Solaris下的API函数几下就搞定了。对于咱们这种手没有那么高的一般人,对还远远没有达到草木竹石均可为剑境界的凡人来说,难道非要熬上N个通宵再加上N的N次方的调试?
非也!
牛顿告诉我们:若能站在巨人的肩上,岂不是能做得更好?我国古人则说:工欲善其事,必先利其器。
如果能够觅得传说中的巨人,寻到那传说中的利器,一切还不迎刃而解?
就在这个伟大的时刻,ACE横空出世!
ACE的全名是ADAPTIVE Communication Environment,是一组可以自由使用的(免费?)、开放源码的面向对象(OO)的构架。使用它可以藐视各个平台间的差异,大大地简化网络编程,减少出错的机会,而且更可以――打住!且先把这茬儿说清楚。
ACE对各个操作系统的接口函数API进行封装,并且用统一的接口形式提供给程序员。换句话说,你只需要简单地调用ACE提供的函数形式(这些形式和常见的系统API非常相像),ACE就会自动地把它转换成你所在的平台上的函数:VxWorks的,或者Solaris,当然更不用说大名鼎鼎的WINDOWS和Linux了。实现方式么,用脚指头都能想出来:使用了非常多的条件编译,把不同系统上的功能相似的API函数统一起来,如果没有则模拟实现,如果有则简单地inline就可以了,还可以不折损效率。此其一也!
想不到还有其二吧?ACE将面向对象的思想运用到这些函数里面,对网络编程等部分的功能进行改造,建立起面向对象的模型。比如,ACE将连接的一方处理成为一个对象,将一个连接处理成为一个对象,先前的操作则被封装成为对象的功能。切不可小觑这一点。要知道,这样就可以运用面向对象的思想来构建应用,而且OO的类型保护机制可以把一大批错误从运行时提前到编译阶段。当然,如果有谁特别有个性,特别喜欢用那种C语言的函数方式的,ACE也提供有那样的形式的函数来满足这种不一般的胃口。
光说不练是没有用的,且让我用一个小例子来镇一镇那些不服的眼睛。(限于篇幅,我只在这里列出最核心的代码:
-
- int main(int, char *[])
- {
- ACE_INET_Addr port_to_listen (9999);
- ACE_SOCK_Acceptor acceptor;
-
- acceptor.open (port_to_listen, 1);
-
- while (1)
- {
- ACE_SOCK_Stream peer;
- ACE_INET_Addr peer_addr;
- ACE_Time_Value timeout (10, 0);
-
- if( 0 == acceptor.accept (peer, &peer_addr, &timeout, 0))
- {
-
- char buffer[4096];
- ssize_t bytes_received;
-
- while ((bytes_received = peer.recv (buffer, sizeof(buffer))) != -1)
- {
- peer.send_n (buffer, bytes_received);
- }
- peer.close ();
- }
- }
-
- return 0;
- }
复制代码 寥寥数行代码,就已经实现了一个完整的服务器:它在9999端口上开始侦听,接受一个TCP连接,把它发过来的数据返还回去。如果业务完成,则断开连接,接受下个连接,开始下一个循环。只要给这段代码包含进需要的头文件,加上几句错误处理,放到ACE的编译环境下――无论是WINDOWS, Linux的,还是UNIX的――都可以编译运行。
如果ACE的功能仅限于此,可能还不足以支持它取得如此大的成就:ACE在西方的应用已经遍及电信、航空、保险、军事、天文、游戏等众多的领域。事实上,上面所说的功能仅仅占据了ACE代码的10%左右。剩下的部分,ACE实现了更为了不起的功能。
ACE融合通讯领域的各个优秀的模式,利用它已经建立起来的可移植到多平台的OS层函数(就是上面所说的那一部分),建立起一个个精巧的框架。这些模式都是作者等众多的工程师在实践中积累起来的优秀经验。实际上,利益于开源的思想,现在全世界有一千七百多位工作者和数百人的核心团队进行ACE的进一步开发。可以这么说,使用ACE,你不是站在一位巨人的肩膀上,而是站在全世界一千七百多人的肩膀上。由此你只需对现有框架进行扩展,大大缩短开发的过程,并且极大地提高程序对硬件的使用效率――而这是已经被证明的。
ACE主要提供以下几种框架供网络程序的开发:
l 事件多路分离组件:ACE Reactor(反应堆)和Proactor(前摄器)是可扩展的面向对象多路分离器,它们分派应用特有的处理器,以响应多种类型的基于I/O、定时器、信号和同步的事件。 l 服务初始化组件:ACE Acceptor(接受器)和Connector(连接器)组件分别使主动和被动的初始化任务与初始化一旦完成后通信服务所执行的应用特有的任务去耦合。 l 进程和线程管理:提供多进程和多线程的派生和管理方法,消除了平台的差异性。 l 服务配置组件:ACE Service Configurator(服务配置器)支持应用的配置,这些应用的服务可在安装时和/或运行时动态装配。 l 分层的流组件:ACE Stream组件简化了像用户级协议栈这样的由分层服务组成的通信软件应用的开发。 l 命名服务:ACE NamingService提供了单进程命名上下文、同一节点共享命名上下文和在网络上命名上下文的服务设施。 除此以外,ACE还提供了信号、线程安全与同步、内存管理等等多种丰富的功能。ACE已经成长成为一个完善的系统,在网络编程方面,能够提供非常丰富的服务。
ACE会因此而满足吗?当然不,那样它只能逐渐被淘汰。当前ACE正在完善它的高级分布式计算中间件组件,并且制定了多个项目计划进一步扩充和发展ACE的功能。所以,使用ACE不用担心所学的知识会因时间而贬值,而事实上正好与此相反。
利剑在手,当然要学会怎么运用才能发挥它的最大功用了。ACE的创建者为我们写好了三本教材,一套两卷的《C++网络编程》和一本《ACE程序员指南》,都有中译本发行。此外,网上有资料可供查询。如果对ACE的设计感兴趣,那再简单不过了:你可以阅读它的全部的源代码:ACE是完全开源的! |