﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-woaidongmao-随笔分类-网络编程</title><link>http://www.cppblog.com/woaidongmao/category/6784.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 22:19:38 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 22:19:38 GMT</pubDate><ttl>60</ttl><item><title>C++网络编程 ACE相关资料收集</title><link>http://www.cppblog.com/woaidongmao/archive/2008/04/18/47534.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Fri, 18 Apr 2008 12:48:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/04/18/47534.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/47534.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/04/18/47534.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/47534.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/47534.html</trackback:ping><description><![CDATA[<p>2008-04-04 14:44  <p>小飞驴的网站 <a href="http://www.flyingdonkey.com/">http://www.flyingdonkey.com/</a> 马维达 C++网络编程 卷二 译者  <p><a href="http://www.flyingdonkey.com/cgi-bin/LB5000MX/leoboard.cgi">http://www.flyingdonkey.com/cgi-bin/LB5000MX/leoboard.cgi</a><br>WeiZone 我们的社区 <a href="http://www.weizone.com/forumdisplay.php?fid=22&amp;page=1">http://www.weizone.com/forumdisplay.php?fid=22&amp;page=1</a> ACE网络通讯编程版  <p>LoveUnix技术论坛 <a href="http://www.loveunix.com/viewthread.php?tid=29276">http://www.loveunix.com/viewthread.php?tid=29276</a><br>hxh（贺星河）的专栏 <a href="http://blog.csdn.net/hxhbluestar/category/25379.aspx">http://blog.csdn.net/hxhbluestar/category/25379.aspx</a> ACE网络编程<br>ACE自适配通信环境讨论 <a href="http://www.huihoo.org/chat/ace_20030702.html">http://www.huihoo.org/chat/ace_20030702.html</a><br><strong>[ACE技术论文集]</strong><a href="http://bbs.lupaworld.com/htm_data/90/0510/9806.html"><strong>一.ACE自适配通信环境：用于开发通信软件的面向对象网络编程工具包</strong></a><br><a href="http://bbs.lupa.gov.cn/read.php?fid=96&amp;tid=7460&amp;toread=1"><strong>ACE程序入口函数替换机制分析</strong></a><br><a href="http://bbs.lupaworld.com/read.php?tid=10478&amp;keyword=ACE">[ACE技术论文集]二 包装外观（Wrapper Facade）：用于在类中封装函数的结构型模式</a> <img alt="精华帖标志" src="http://bbs.lupaworld.com/1123515557/wind/file/digest_1.gif"><br><a href="http://bbs.lupaworld.com/read.php?tid=10725&amp;keyword=ACE">[ACE技术论文集]三 IPC SAP：用于高效、可移植和灵活的网络编程的C++包装</a><br><a href="http://bbs.lupaworld.com/read.php?tid=10740&amp;keyword=ACE">[ACE技术论文集]四 ACE轻量级OS并发机制的OO封装</a><br><a href="http://bbs.lupaworld.com/read.php?tid=10983&amp;keyword=ACE">[ACE技术论文集]五 C/C++线程专有存储：用于访问“per-Thread”状态的对象行为模式</a><br><a href="http://bbs.lupaworld.com/read.php?tid=9802&amp;keyword=ACE">ACE的类结构图[pdf文档]</a><br>ACE自适配通信环境<br>Douglas C. Schmidt<br>一、ACE综述<br>　　ACE自适配通信环境（ADAPTIVE Communication Environment）是可以自由使用、开放源码的面向对象（OO）框架（Framework），在其中实现了许多用于并发通信软件的核心模式。ACE提供了一组丰富的可复用C++ Wrapper Facade（包装外观）和框架组件，可跨越多种平台完成通用的通信软件任务，其中包括：事件多路分离和事件处理器分派、信号处理、服务初始化、进程间通信、共享内存管理、消息路由、分布式服务动态（重）配置、并发执行和同步，等等。<br>ACE的目标用户是高性能和实时通信服务和应用的开发者。它简化了使用进程间通信、事件多路分离、显式动态链接和并发的OO网络应用和服务的开发。此外，通过服务在运行时与应用的动态链接，ACE还使系统的配置和重配置得以自动化。<br>ACE正在进行持续的改进。Riverace公司（<a href="http://www.riverace.com/">http://www.riverace.com</a>）采用开放源码商业模式对ACE进行商业支持。此外，ACE开发组的许多成员目前正在进行The ACE ORB（TAO，<a href="http://www.cs.wustl.edu/~schmidt/TAO.html">http://www.cs.wustl.edu/~schmidt/TAO.html</a>）的开发工作。<br>二、使用ACE的好处<br>使用ACE的好处有：<br>l&nbsp;&nbsp;&nbsp; 增强可移植性：在ACE组件的帮助下，很容易在一种OS平台上编写并发网络应用，然后快速地将它们移植到各种其他的OS平台上。而且，因为ACE是开放源码的自由软件，你无需担心被锁定在特定的操作系统平台或编译器上。<br>l&nbsp;&nbsp;&nbsp; 更好的软件质量：ACE的设计使用了许多可提高软件质量的关键模式，这些质量因素包括通信软件灵活性、可扩展性、可复用性和模块性。<br>l&nbsp;&nbsp;&nbsp; 更高的效率和可预测性：ACE经仔细设计，支持广泛的应用服务质量（QoS）需求，包括延迟敏感应用的低响应等待时间、高带宽应用的高性能，以及实时应用的可预测性。<br>l&nbsp;&nbsp;&nbsp; 更容易转换到标准的高级中间件：TAO使用了ACE提供的可复用组件和模式。它是CORBA的开发源码、遵循标准的实现，并为高性能和实时系统作了优化。为此，ACE和TAO被设计为能良好地协同工作，以提供全面的中间件解决方案。<br>三、ACE的结构和功能 <br>下图显示了ACE中的关键组件以及它们的层次关系： <br>图中的结构和各层的组成部分描述如下。<br>四、ACE OS适配层<br>该层直接位于用C写成的本地OS API之上。它提供轻型的类POSIX OS适配层，将ACE中的其他层及组件和以下与OS API相关联的平台专有特性屏蔽开来：<br>l&nbsp;&nbsp;&nbsp; 并发和同步：ACE的适配层封装了用于多线程、多进程和同步的OS API。<br>l&nbsp;&nbsp;&nbsp; 进程间通信（IPC）和共享内存：ACE的适配层封装了用于本地和远地IPC、以及共享内存的OS API。<br>l&nbsp;&nbsp;&nbsp; 事件多路分离机制：ACE的适配层封装了用于对基于I/O、定时器、信号和同步的事件进行同步和异步多路分离的OS API。<br>l&nbsp;&nbsp;&nbsp; 显式动态链接：ACE的适配层封装了用于显式动态链接的OS API。显式动态链接允许在安装时或运行时对应用服务进行配置。<br>l&nbsp;&nbsp;&nbsp; 文件系统机制：ACE的适配层封装了用于操作文件和目录的OS文件系统API。<br>ACE OS适配层的可移植性使得ACE可运行在许多操作系统上。ACE已在广泛的OS平台上进行了移植和测试，包括Win32（也就是，在Intel和Alpha平台，使用MSVC++、Borland C++ Builder和IBM Visual Age的WinNT 3.5.x、4.x、2000、Win95/98和WinCE）、Mac OS X、大多数版本的UNIX（例如，SPARC和Intel上的Solaris 1.x和2.x、SGI IRIX 5.x和6.x、DG/UX、HP-UX 9.x、10.x和11.x、DEC/Compaq UNIX 3.x和4.x、AIX 3.x和4.x、UnixWare、SCO，以及可自由使用的UNIX实现，比如Debian Linux 2.x、RedHat Linux 5.2、6.x和7.x、FreeBSD和NetBSD）、实时操作系统（比如，LynxOS、VxWorks、Chorus ClassiX 4.0、QnX Neutrino、RTEMS和PSoS）、MVS OpenEdition和CRAY UNICOS。<br>由于ACE的OS适配层所提供的抽象，所有这些平台使用同一棵代码树。这样的设计极大地增强了ACE的可移植性和可维护性。此外，还有Java版本的ACE可用（<a href="http://www.cs.wustl.edu/~eea1/JACE.html">http://www.cs.wustl.edu/~eea1/JACE.html</a>）。<br>五、OS接口的C++ Wrapper Facade<br>可以直接在ACE OS适配层之上编写高度可移植的C++应用。但是，大多数ACE开发者使用的是上图中所示的C++ Wrapper Facade层。通过提供类型安全的C++接口（这些接口封装并增强本地的OS并发、通信、内存管理、事件多路分离、动态链接和文件系统API），ACE Wrapper Facade简化了应用的开发。应用可以通过有选择地继承、聚合和/或实例化下面的组件来组合和使用这些包装：<br>l&nbsp;&nbsp;&nbsp; 并发和同步组件：ACE对像互斥体和信号量这样的本地OS多线程和多进程机制进行抽象，以创建高级的OO并发抽象，像主动对象（Active Object）和多态期货（Polymorphic Future）。<br>l&nbsp;&nbsp;&nbsp; IPC和文件系统组件：ACE C++包装对本地和/或远地IPC机制进行封装，比如socket、TLI、UNIX FIFO和STREAM管道，以及Win32命名管道。此外，ACE C++包装还封装了OS文件系统API。<br>l&nbsp;&nbsp;&nbsp; 内存管理组件：ACE内存管理组件为管理进程间共享内存和进程内堆内存的动态分配和释放提供了灵活和可扩展的抽象。<br>ACE C++包装提供了许多与ACE OS适配层一样的特性。但是，这些特性是采用C++类和对象、而不是独立的C函数来构造的。这样的OO包装有助于减少正确地学习和使用ACE所需的努力。<br>例如，C++的使用提高了应用的健壮性，因为C++包装是强类型的。所以，编译器可在编译时、而不是运行时检测类型系统违例。相反，不到运行时，不可能检测像socket或文件系统I/O这样的C一级OS API的类型系统违例。<br>ACE采用了许多技术来降低或消除额外的性能开销。例如，ACE大量地使用C++内联来消除额外的方法调用开销；这样的开销可由OS适配层和C++包装所提供的额外的类型安全和抽象层次带来。此外，对于性能要求很高的包装，比如socket和文件I/O的send/recv方法，ACE会避免使用虚函数。<br>六、框架<br>ACE还含有一个高级的网络编程框架，集成并增强了较低层次的C++ Wrapper Facade。该框架支持将并发分布式服务动态配置进应用。ACE的框架部分包含以下组件：<br>l&nbsp;&nbsp;&nbsp; 事件多路分离组件：ACE Reactor(反应器)和Proactor（前摄器）是可扩展的面向对象多路分离器，它们分派应用特有的处理器，以响应多种类型的基于I/O、定时器、信号和同步的事件。<br>l&nbsp;&nbsp;&nbsp; 服务初始化组件：ACE Acceptor（接受器）和Connector（连接器）组件分别使主动和被动的初始化任务与初始化一旦完成后通信服务所执行的应用特有的任务去耦合。<br>l&nbsp;&nbsp;&nbsp; 服务配置组件：ACE Service Configurator（服务配置器）支持应用的配置，这些应用的服务可在安装时和/或运行时动态装配。<br>l&nbsp;&nbsp;&nbsp; 分层的流组件：ACE Stream组件简化了像用户级协议栈这样的由分层服务组成的通信软件应用的开发。<br>l&nbsp;&nbsp;&nbsp; ORB适配器组件：通过ORB适配器，ACE可以与单线程和多线程CORBA实现进行无缝集成。<br>ACE框架组件便利了通信软件的开发，它们无需修改、重编译、重链接，或频繁地重启运行中的应用，就可被更新和扩展。在ACE中，这样的灵活性是通过结合以下要素来获得的：（1）C++语言特性，比如模板、继承和动态绑定，（2）设计模式，比如抽象工厂、策略和服务配置器，以及（3）OS机制，比如显式动态链接和多线程。<br>七、分布式服务和组件 <br>除了OS适配层、C++ Wrapper Facade和框架组件，ACE还提供了包装成自包含组件的标准分布式服务库。尽管这些服务组件并不是ACE框架库的严格组成部分，它们在ACE中扮演了两种角色：<br>1.&nbsp;&nbsp;&nbsp; 分解出可复用分布式应用的“积木”：这些服务组件提供通用的分布式应用任务的可复用实现，比如名字服务、事件路由、日志、时间同步和网络锁定。<br>2.&nbsp;&nbsp;&nbsp; 演示ACE组件的常见用例：这些分布式服务还演示了怎样用像Reactor、Service Configurator、Acceptor和Connector、Active Object，以及IPC包装这样的ACE组件来有效地开发灵活、高效和可靠的通信软件。<br>八、高级分布式计算中间件组件<br>即使使用像ACE这样的通信框架，开发健壮、可扩展和高效的通信应用仍富有挑战性。特别是，开发者必须掌握许多复杂的OS和通信的概念，比如：<br>l&nbsp;&nbsp;&nbsp; 网络寻址和服务标识。<br>l&nbsp;&nbsp;&nbsp; 表示转换，比如加密、压缩和在异种终端系统间的字节序转换。<br>l&nbsp;&nbsp;&nbsp; 进程和线程的创建和同步。<br>l&nbsp;&nbsp;&nbsp; 本地和远地进程间通信（IPC）机制的系统调用和库例程。<br>通过采用像CORBA、DCOM或Java RMI这样的高级分布式计算中间件，可以降低开发通信应用的复杂性。高级分布式计算中间件驻留在客户端和服务器之间，可自动完成分布式应用开发的许多麻烦而易错的方面，包括：<br>l&nbsp;&nbsp;&nbsp; 认证、授权和数据安全。<br>l&nbsp;&nbsp;&nbsp; 服务定位和绑定。<br>l&nbsp;&nbsp;&nbsp; 服务注册和启用。<br>l&nbsp;&nbsp;&nbsp; 事件多路分离和分派。<br>l&nbsp;&nbsp;&nbsp; 在像TCP这样的面向字节流的通信协议之上实现消息帧。<br>l&nbsp;&nbsp;&nbsp; 涉及网络字节序和参数整编（marshaling）的表示转换问题。<br>为给通信软件的开发者提供这些特性，在ACE中绑定了下面的高级中间件应用：<br>1.&nbsp;&nbsp;&nbsp; The ACE ORB（TAO）：TAO是使用ACE提供的框架组件和模式构建的CORBA实时实现，包含有网络接口、OS、通信协议和CORBA中间件组件等特性。TAO基于标准的OMG CORBA参考模型，并进行了增强的设计，以克服传统的用于高性能和实时应用的ORB的缺点。TAO像ACE一样，也是可自由使用的开放源码软件。<br>2.&nbsp;&nbsp;&nbsp; JAWS：JAWS是高性能、自适配的Web服务器，使用ACE提供的框架组件和模式构建。JAWS被构造成“框架的框架”。JAWS的总体框架含有以下组件和框架：事件多路分派器、并发策略、I/O策略、协议管道、协议处理器和缓存虚拟文件系统。每个框架都被构造成一组协作对象，通过组合和扩展ACE中的组件来实现。JAWS也是可自由使用的开放源码软件。<br>九、主页<br>ACE的主页为：<a href="http://www.cs.wustl.edu/~schmidt/ACE.html">http://www.cs.wustl.edu/~schmidt/ACE.html</a>，在这里可获得最新版本的ACE以及其他相关资源。<br>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝  <p>网络通信<br>ACE<br>参考网站：<a href="http://www.c%20%3ehttp//www.c%20%3Ehttp://www.c%20%3Ehttp://www.cs.wustl.edu/~schmidt/ACE.html">http://www.c'&gt;http://www.c'&gt;http://www.c'&gt;http://www.cs.wustl.edu/~schmidt/ACE.html</a><br>C++库的代表，超重量级的网络通信开发框架。ACE自适配通信环境（Adaptive Communication Environment）是可以自由使用、开放源代码的面向对象框架，在其中实现了许多用于并发通信软件的核心模式。ACE提供了一组丰富的可复用C++包装外观（Wrapper Facade）和框架组件，可跨越多种平台完成通用的通信软件任务，其中包括：事件多路分离和事件处理器分派、信号处理、服务初始化、进程间通信、共享内存管理、消息路由、分布式服务动态（重）配置、并发执行和同步，等等。<br>StreamModule<br>参考网站：<a href="http://www.omnifarious.org/StrMod/%20%3Ehttp://www.omnifarious.org/StrMod/">http://www.omnifarious.org/StrMod/'&gt;http://www.omnifarious.org/StrMod/</a><br>设计用于简化编写分布式程序的库。尝试着使得编写处理异步行为的程序更容易，而不是用同步的外壳包起异步的本质。<br>SimpleSocket<br>参考网站：<a href="http://home.hetnet.nl/~lcbokkers/simsock.htm">http://home.hetnet.nl/~lcbokkers/simsock.htm</a><br>这个类库让编写基于socket的客户/服务器程序更加容易。<br>A Stream Socket API for C++<br>参考网站：<a href="http://www.pcs.cnu.edu/%20%3Ehttp://www.pcs.cnu.edu/~dgame/sockets/socketsC++/sockets.html">http://www.pcs.cnu.edu/'&gt;http://www.pcs.cnu.edu/~dgame/sockets/socketsC++/sockets.html</a><br>又一个对Socket的封装库。  <p><a href="http://blog.donews.com/dgsheng/archive/2006/03/16/771372.aspx">http://blog.donews.com/dgsheng/archive/2006/03/16/771372.aspx</a>  <p>ACE将网络编程进行了模式化，以便你不必每次都重复相同的代码。  <p>网络编程需要处理的事情多括中断，并发，多线程等，程序格式相对固定，但是健壮的网络程序则相对复杂。为了处理这些情形，ACE内建了几个网络编程的模式。  <p>最基本的模式当然是直接使用sock进行单客户单服务器单线程的一对一模型，这种模式相对简单，也和ACE关系不大，但是这样编写的程序不能处理并发的情况，可用性很差或者说基本不具有可用性。  <p>最简单的处理并发但是却使用单线程的框架在ACE中称为Reactor框架，在这种框架下，Reactor扮演了协调员的角色，应用程序编制者需要首先写好各种各样的事件处理程序，然后在Reactor中进行登记，Reactor以阻塞的方式同时监视所有可能发生的事件，并且在相应的事件发生的时候调用对应的处理过程。这种框架解决了在单线程的前提下解决了并发，但是存在一定的问题，如果某个事件执行过程过长，则可能导致Reactor漏过某些事件。  <p>另外一种单线程处理并发的模式称为异步I/O的Proactor模式，这种模式和前面介绍的Reactor模式其实区别不大，唯一的区别之处在于，Server类在对从网络上收到的消息进行处理的时候，后者并不直接让处理器处理收到的消息，而是首先将消息转换为一个消息块结构(ACE_Message_Block，通过this-&gt;reader_.read函数)，然后再让相应的处理函数处理已经接收好的消息块结构。  <p>比较一下Reactor框架和Proactor框架，前者的执行流程是： 监视事件-&gt;调用事件处理过程-&gt;继续监视事件。 后者的执行流程是： 监视事件-&gt;产生消息-&gt;处理消息-&gt;释放消息-&gt;继续监视事件。这两种不同的框架在引入各自的多线程概念以后，就衍生出不同的多线程框架。  <p>前面说过，使用多线程进行网络编程也有两种框架，半同步/半异步框架和领导者/跟随者框架。前者对应的是Proactor框架，后者对应的是Reactor框架。所谓半同步或者半异步框架，执行的流程是：主线程负责 监视事件-&gt;产生消息-&gt;放入消息队列-&gt;监视事件,工作线程则负责从获取消息-&gt;处理消息-&gt;从消息队列获取另外一个消息。 这种框架的优势在于，由于构造消息并且将其放入消息队列的时间是可以控制的，因此，可以很好的处理网络峰值的情况，即使出现很高的峰值，也不会造成消息的遗漏，但是由于消息存在一个入队列，出队列的过程，因此性能相较另外一种模型，理论上更差。  <p>后者则是一种相对更复杂的模型，在线程池中只有一个线程是领导者线程，其他为跟随者线程，领导者线程监视事件，在事情发生的时候，首先寻找另外一个线程变为领导者，然后自己再处理事件，处理完成以后，首先尝试再次成为领导者，如果尝试失败（另外一个线程已经成为领导者），则自己变成跟随者。 这种模型基于Reactor模型，没有消息队列的概念，由于不存在出入队列的过程，性能相对前者理论上更好。但是如果存在很高的网络蜂拥，则可能由于所有的线程都在处理各自的事件，导致没有领导者可用，出现数据丢失的可能。  <p>在这两种多线程模型中都存在线程池的使用。在半同步/半异步模型中，工作者线程可能为一个工作者线程池。消息队列的线程同步的工作已经由ACE框架自动完成，是不是工作者线程越多越好呢？ 答案是否定的。 多线程可以提高客户的响应速度。比如同时有A，B两个客户端先后发起两个请求，A请求完成的时间较长，B请求则可以很快完成，如果只有一个工作线程，那么B需要等待A请求完成以后才能收到自己的响应，对于A来说，它本来就不期待自己的请求很快被完成，实际的执行情况会是，A在期待的时间内收到响应，B则使用了A的时间才收到自己的响应，B的客户满意度就会很差。 如果使用多线程，A会延迟一点点收到自己的响应，而B也可以在合理的时间内收到自己的响应。 但是由于多线程有自己的开销，就整个系统来说，单工作线程执行A和B的总时间回比多工作线程执行AB任务的总时间要短。  <p>对于领导者/跟随者模型中，必然存在一个对等的线程池，线程池的数目取决于系统能够承受的数目，单就对于模型本身来说，线程池的线程数目越大，能够承受的网络蜂拥的极限值也越大。 但是如果执行每个请求的时间都很短，则系统中存在大量永远也用不到的线程，浪费了系统的资源。  <p>如果使用多处理器的系统，应用程序必然能够从多线程（工作线程和跟随者线程）结构中收益  <img src ="http://www.cppblog.com/woaidongmao/aggbug/47534.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-04-18 20:48 <a href="http://www.cppblog.com/woaidongmao/archive/2008/04/18/47534.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ACE与ASIO之间关于Socket编程的比较</title><link>http://www.cppblog.com/woaidongmao/archive/2008/04/18/47532.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Fri, 18 Apr 2008 12:47:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/04/18/47532.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/47532.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/04/18/47532.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/47532.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/47532.html</trackback:ping><description><![CDATA[<p>ACE与ASIO之间关于Socket编程的比较<br>转自：<a href="http://hi.baidu.com/itengfei/blog/item/69e7a01ff0612761f724e468.html">FREE MY SOUL</a><br>ACE是一个很成熟的中间件产品，为自适应通讯环境，但它过于宏大，一堆的设计模式，架构是一层又一层，对初学者来说，有点困难。<br>ASIO是基本Boost开发的异步IO库，封装了Socket，简化基于socket程序的开发。<br>最近分析ASIO的源代码，让我无不惊呀于它设计。在ACE中开发中的内存管理一直让人头痛，ASIO的出现，让我看到新的曙光，成为我新的好伙伴。简单地与ACE做个比较。<br>1.层次架构：<br>ACE底层是C风格的OS适配层，上一层基于C++的wrap类，再上一层是一些框架（Accpetor, Connector，Reactor等），最上一层是框架上服务。<br>ASIO与之类似，底层是OS的适配层，上一层一些模板类，再上一层模板类的参数化（TCP/UDP），再上一层是服务，它只有一种框架为io_service。<br>2.涉及范围：<br>ACE包含了日志，IPC，线程，共享内存，配置服务等。<br>ASIO只涉及到Socket，提供简单的线程操作。<br>3.设计模式：<br>ACE主要应用了Reactor，Proactor等。<br>而ASIO主要应用了Proactor。<br>4.线程调度：<br>ACE的Reactor是单线程调度，Proactor支持多线程调度。<br>ASIO支持单线程与多线程调度。<br>5.事件分派处理：<br>ACE主要是注册handler类，当事件分派时，调用其handler的虚挂勾函数。实现ACE_Handler/ACE_Svc_Handler/ACE_Event_handler等类的虚函数。<br>ASIO是基于函数对象的hanlder事件分派。任何函数都可能成功hanlder，少了一堆虚表的维护，调度上优于ACE。<br>6.发布方式：<br>ACE是开源免费的，不依赖于第3方库， 一般应用使用它时，以动态链接的方式发布动态库。<br>ASIO是开源免费的，依赖Boost，应用使用时只要include头文件，不需动态库。<br>7.可移植性：<br>ACE支持多种平台，可移植性不存在问题，据说socket编程在linux下有不少bugs。<br>ASIO支持多种平台，可移植性不存在问题。<br>8.开发难度：<br>基于ACE开发应用，对程序员要求比较高，要用好它，必须非常了解其框架。在其框架下开发，往往new出一个对象，不知在什么地方释放好。<br>基于ASIO开发应用，要求程序员熟悉函数对象，函数指针，熟悉boost库中的boost::bind。内存管理控制方便。<br>我个人觉得，如果应用socket编程，使用ASIO开发比较好，开发效率比较高。ACE适合于理论研究，它本来就是源于Douglas的学术研究。  <p>posted on 2007-09-21 10:27 <a href="http://www.cppblog.com/jinq0123/">金庆</a> 阅读(606) <a href="http://www.cppblog.com/#Post">评论(16)</a> <a href="http://www.cppblog.com/jinq0123/admin/EditPosts.aspx?postid=32603">编辑</a> <a href="http://www.cppblog.com/jinq0123/AddToFavorite.aspx?id=32603">收藏</a> <a href="http://www.cppblog.com/jinq0123/services/trackbacks/32603.aspx">引用</a> 所属分类: <a href="http://www.cppblog.com/jinq0123/category/5137.html">1. C/C++</a>  <p><img height="1" src="http://www.cppblog.com/jinq0123/aggbug/32603.html?webview=1" width="1">  <p><a name="pagedcomment"></a><a name="评论"> <h5>评论</h5> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#32645">#</a> <a name="32645"></a>re: ACE与ASIO之间关于Socket编程的比较 2007-09-21 23:01 <a href="http://www.cppblog.com/missdeer/">missdeer</a>  <p>发现asio占用CPU很厉害，而且不知道是不是我用得不对，传输效率并不高。。。&nbsp; <a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=missdeer">更多评论</a><br><a href="http://www.cppblog.com/"></a><a></a> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#32655">#</a> <a name="32655"></a>re: ACE与ASIO之间关于Socket编程的比较 2007-09-22 10:15 <a href="http://www.cppblog.com/jinq0123/">金庆</a>  <p>@missdeer<br>ACE，asio都没用过。只是用了boost中几个库之后，对boost有好感。以前的网络编程都是直接用socket。是否选用asio还需要自己考察。&nbsp; <a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=%e9%87%91%e5%ba%86">更多评论</a><br><a href="http://www.cppblog.com/"></a><a></a> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#32791">#</a> <a name="32791"></a>re: ACE与ASIO之间关于Socket编程的比较[未登录] 2007-09-24 16:16 <a>exile</a>  <p>asio本身并不占用多少资源, 如果网络连接数不多,但占用CPU很厉害, 那肯定时是自己写的程序某个地方出了问题.&nbsp; <a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=exile">更多评论</a><br><a href="http://www.cppblog.com/"></a><a></a> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#32814">#</a> <a name="32814"></a>re: ACE与ASIO之间关于Socket编程的比较 2007-09-24 23:34 <a href="http://www.cppblog.com/missdeer/">missdeer</a>  <p>@exile<br>我也希望是自己写的代码的问题，毕竟要选择用一个框架来进行开发，对于一个稳重的项目组来说是很大的一个决心。可是我用的测试代码就是asio自带的例子程序，其它相关的文档提及的也少……&nbsp; <a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=missdeer">更多评论</a><br><a href="http://www.cppblog.com/"></a><a></a> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#32833">#</a> <a name="32833"></a>re: ACE与ASIO之间关于Socket编程的比较[未登录] 2007-09-25 10:56 <a>eXile</a>  <p>@missdeer <br>那就应该分析一下测试的环境. 看一下有连接时,无连接时, 局域网中, 公网中. <br>asio本身带的例子是很简单的, 都是用法演示,最多也就服务器设定几个线程. <br>在局域网中进行这样的测试是没有什么意义的. <br>boost 的 thread 和asio都是有可能作为系统支持库进入std::tr2的. <br><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=eXile">更多评论</a><br><a href="http://www.cppblog.com/"></a><a></a> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#33032">#</a> <a name="33032"></a>re: ACE与ASIO之间关于Socket编程的比较 2007-09-27 17:05 <a href="http://www.cppblog.com/jinq0123/">金庆</a>  <p>@missdeer<br>我下载了asio 0.3.8准备试试它的例子。不过发现asio不支持VC6。boost其它库都是支持VC6的，而asio只支持VC7.1和VC8。&nbsp; <a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=%e9%87%91%e5%ba%86">更多评论</a><br><a href="http://www.cppblog.com/"></a><a></a> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#33057">#</a> <a name="33057"></a>re: ACE与ASIO之间关于Socket编程的比较 2007-09-27 21:53 <a href="http://www.cppblog.com/missdeer/">missdeer</a>  <p>@金庆<br>如果要用Boost之类的模板库，强烈建议放弃VC6，改用7.1或8.0，无论从编译器对标准的兼容，还是第三方库对编译器的支持上看，7.1都远远好于6.0&nbsp; <a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=missdeer">更多评论</a><br><a href="http://www.cppblog.com/"></a><a></a> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#33073">#</a> <a name="33073"></a>re: ACE与ASIO之间关于Socket编程的比较 2007-09-28 09:06 <a href="http://www.cppblog.com/jinq0123/">金庆</a>  <p>@missdeer<br>我想的是放弃VC。只要我掌握了wxWidgets，就可以抛弃MFC，然后抛弃VC。&nbsp; <a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=%e9%87%91%e5%ba%86">更多评论</a><br><a href="http://www.cppblog.com/"></a><a></a> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#33122">#</a> <a name="33122"></a>re: ACE与ASIO之间关于Socket编程的比较 2007-09-28 20:36 <a>BlueEngine</a>  <p>问个问题：看上了wxWidgets的i18n，如何利用它来实现现有MFC程序的国际化？各位朋友请给个建议。&nbsp; <a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=BlueEngine">更多评论</a><br><a href="http://www.cppblog.com/"></a><a></a> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#33177">#</a> <a name="33177"></a>re: ACE与ASIO之间关于Socket编程的比较 2007-09-29 09:28 <a href="http://www.cppblog.com/jinq0123/">金庆</a>  <p>@BlueEngine<br>以前做过MFC两套资源来实现中英语言版本。如是只是两个语言，就没必要用i18n。当然如果会用wxWidgets的i18n，或者用过，可能选它是正确的选择。&nbsp; <a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=%e9%87%91%e5%ba%86">更多评论</a><br><a href="http://www.cppblog.com/"></a><a></a> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#39044">#</a> <a name="39044"></a>re: ACE与ASIO之间关于Socket编程的比较 2007-12-19 15:37 <a href="http://www.cppblog.com/jinq0123/">金庆</a>  <p>@missdeer<br>不知占用CPU很厉害的原因找到没有？我试了asio的几个例子，都还不错。只要理解了Proactor模式，使用上应该是相当方便的。&nbsp; <a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=%e9%87%91%e5%ba%86">更多评论</a><br><a href="http://www.cppblog.com/"></a><a></a> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#39073">#</a> <a name="39073"></a>re: ACE与ASIO之间关于Socket编程的比较[未登录] 2007-12-19 21:30 <a>missdeer</a>  <p>平常小数据量传输是看不出什么，但如果数据量一大，就很明显了，你可以试试它的一个http client例子，让它下载一个1M大小的文件，不管你的网络环境如何，都会很占CPU。&nbsp; <a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=missdeer">更多评论</a><br><a href="http://www.cppblog.com/"></a><a></a> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#39122">#</a> <a name="39122"></a>re: ACE与ASIO之间关于Socket编程的比较 2007-12-20 15:23 <a href="http://www.cppblog.com/ly4cn/">沐枫</a>  <p>从版本号也能看出来。asio目前只有0.3.9，还远未到开发完整。<br>因此，成熟自然也远未到。&nbsp; <a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=%e6%b2%90%e6%9e%ab">更多评论</a><br><a href="http://www.cppblog.com/"></a><a></a> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#39134">#</a> <a name="39134"></a>re: ACE与ASIO之间关于Socket编程的比较 2007-12-20 17:11 <a href="http://www.cppblog.com/jinq0123/">金庆</a>  <p>测了一下，确实是这样。对于内网传输CPU占满了，对外网（网速很低）没有明显的CPU占用。与网络环境无关吗？如果是低流量时占CPU，那肯定是有问题。数据流量大时，可以解释为接收数据太忙，不过也是不正常（相比其它下载工具）。&nbsp; <a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=%e9%87%91%e5%ba%86">更多评论</a><br><a href="http://www.cppblog.com/"></a><a></a> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#42123">#</a> <a name="42123"></a>re: ACE与ASIO之间关于Socket编程的比较 2008-01-29 15:08 <a>lunny</a>  <p>asio有两个版本，一个依赖于boost的，将来会加入boot库，同时也会发布一个独立的，并不一定非要用依赖于boost的那个版本。&nbsp; <a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=lunny">更多评论</a><br><a href="http://www.cppblog.com/"></a><a></a> <p><a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#46593">#</a> <a name="46593"></a>re: ACE与ASIO之间关于Socket编程的比较<a name="Post"></a> 2008-04-09 11:14 <a>fafa</a>  <p>@lunny<br>依赖于boost那个版本比较好编译嘛&nbsp; <a href="http://www.cppblog.com/jinq0123/archive/2008/04/09/32603.html#post">回复</a> <a href="http://www.cppblog.com/comment?author=fafa">更多评论</a>  <p></a><img src ="http://www.cppblog.com/woaidongmao/aggbug/47532.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-04-18 20:47 <a href="http://www.cppblog.com/woaidongmao/archive/2008/04/18/47532.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ACE高效PROACTOR编程框架一ClientHandle</title><link>http://www.cppblog.com/woaidongmao/archive/2008/04/18/47533.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Fri, 18 Apr 2008 12:47:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/04/18/47533.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/47533.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/04/18/47533.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/47533.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/47533.html</trackback:ping><description><![CDATA[<p></p> <p>2008-04-02 23:24  <p>1、WIN32下面用proactor可以达到几乎RAW　IOCP的效率，由于封装关系，应该是差那么一点。  <p>客户端处理类的常规写法：<br>//处理客户端连接消息<br>class ClientHandler : public ACE_Service_Handler<br>{<br>public:<br>/**构造函数<br>*<br>*<br>*/<br>ClientHandler(unsigned int client_recv_buf_size=SERVER_CLIENT_RECEIVE_BUF_SIZE)<br>&nbsp;&nbsp; :_read_msg_block(client_recv_buf_size),_io_count(0)<br>{<br>}  <p>~ClientHandler(){}  <p>/**<br>*初始化，因为可能要用到ClientHandler内存池，而这个池又不一定要用NEW<br>*/<br>void init();  <p>/**清理函数，因为可能要用到内存池<br>*<br>*/<br>void fini();  <p>//检查是否超时的函数  <p>void check_time_out(time_t cur_time);  <p>public:  <p>/**客户端连接服务器成功后调用<br>*<br>* \param handle 套接字句柄<br>* \param &amp;message_block 第一次读到的数据（未用）<br>*/  <p>//由Acceptor来调用！！！<br>virtual void open (ACE_HANDLE handle,ACE_Message_Block &amp;message_block);  <p>/**处理网络读操作结束消息<br>*<br>* \param &amp;result 读操作结果<br>*/<br>virtual void handle_read_stream (const ACE_Asynch_Read_Stream::Result &amp;result);  <p>/**处理网络写操作结束消息<br>*<br>* \param &amp;result 写操作结果<br>*/<br>virtual void handle_write_stream (const ACE_Asynch_Write_Stream::Result &amp;result);  <p>private:  <p>//**生成一个网络读请求<br>*<br>* \param void <br>* \return 0-成功，-1失败<br>*/<br>int initiate_read_stream (void);  <p>/**生成一个写请求<br>*<br>* \param mb 待发送的数据<br>* \param nBytes 待发送数据大小<br>* \return 0－成功，－1失败<br>*/<br>int initiate_write_stream (ACE_Message_Block &amp; mb, size_t nBytes );<br>/**<br>*<br>* \return 检查是否可以删除，用的是一个引用计数。每一个外出IO的时候＋1，每一个IO成功后－1<br>*/<br>int check_destroy();<br>//异步读<br>ACE_Asynch_Read_Stream _rs;  <p>//异步写<br>ACE_Asynch_Write_Stream _ws;  <p>//接收缓冲区只要一个就够了，因为压根就没想过要多读，我直到现在也不是很清楚为什么要多读，多读的话要考虑很多问题<br>ACE_Message_Block _read_msg_block;  <p>//套接字句柄,这个可以不要了，因为基类就有个HANDLER在里面的。<br>//ACE_HANDLE _handle;  <p>//一个锁，客户端反正有东东要锁的，注意，要用ACE_Recursive_Thread_Mutex而不是用ACE_Thread_Mutex，这里面是可以重入的，而且在WIN32下是直接的EnterCriticalSection，可以达到很高的效率<br>ACE_Recursive_Thread_Mutex _lock;<br>//在外IO数量,其实就是引用计数啦，没啥的。为0的时候就把这个东东关掉啦。<br>long _io_count;  <p>//检查超时用的，过段时间没东东就CLOSE他了。  <p>time_t _last_net_io;  <p>private:  <p>//本来想用另外一种模型的，只用1个或者2个外出读，后来想想，反正一般内存都是足够的，就不管了。  <p>//ACE_Message_Block _send_msg_blocks[2];  <p>//ACE_Message_Block &amp;_sending_msg_block;  <p>//ACE_Message_Block &amp;_idle_msg_block;  <p>private:<br>public:<br>//TODO:move to prriva and use friend class!!!  <p>//只是为了效率更高，不用STL的LIST是因为到现在我没有可用的Node_Allocator，所以效率上会有问题。<br>ClientHandler *_next;  <p>ClientHandler *next(){return _next;}  <p>void next(ClientHandler *obj){_next=obj;}  <p>};  <p>//这是具体实现，有些地方比较乱，懒得管了，锁的有些地方不对。懒得改了，反正在出错或者有瓶颈的时候再做也不迟。  <p>void ClientHandler::handle_read_stream (const ACE_Asynch_Read_Stream::Result &amp;result)<br>{<br>_last_net_io=ACE_OS::time(NULL);<br>int byterecved=result.bytes_transferred ();<br>if ( (result.success ()) &amp;&amp; (byterecved != 0))<br>{<br>&nbsp;&nbsp; //ACE_DEBUG ((LM_DEBUG, "Receiver completed:%d\n",byterecved));  <p>//处理完数据<br>&nbsp;&nbsp; if(handle_received_data()==true)<br>&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; //ACE_DEBUG ((LM_DEBUG, "go on reading...\n"));  <p>//把东东推到头部，处理粘包<br>&nbsp;&nbsp;&nbsp; _read_msg_block.crunch();<br>&nbsp;&nbsp;&nbsp; initiate_read_stream();<br>&nbsp;&nbsp; }<br>}  <p>//这个地方不想用ACE_Atom_op，因为反正要有一个锁，而且一般都会用锁，不管了。假如不在意的话，应该直接用ACE_Atom_Op以达到最好的效率  <p>{<br>&nbsp;&nbsp; ACE_Guard&lt;ACE_Recursive_Thread_Mutex&gt; locker (_lock);<br>&nbsp;&nbsp; _io_count--;<br>}<br>check_destroy ();<br>}  <p>void ClientHandler::init()<br>{  <p>//初始化数据，并不在构造函数里做。<br>_last_net_io=ACE_OS::time(NULL);<br>_read_msg_block.rd_ptr(_read_msg_block.base());<br>_read_msg_block.wr_ptr(_read_msg_block.base());<br>this-&gt;handle(ACE_INVALID_HANDLE);<br>}  <p>bool ClientHandler::handle_received_data()<br>{  <p>...........自己处理<br>return true;<br>}  <p>//==================================================================<br>void ClientHandler::handle_write_stream (const ACE_Asynch_Write_Stream::Result &amp;result)<br>{<br>//发送成功，RELEASE掉<br>//这个不可能有多个RELEASE，直接XX掉<br>//result.message_block ().release ();<br>MsgBlockManager::get_instance().release_msg_block(&amp;result.message_block());  <p>{<br>&nbsp;&nbsp; ACE_Guard&lt;ACE_Recursive_Thread_Mutex&gt; locker (_lock);<br>&nbsp;&nbsp; _io_count--;<br>}<br>check_destroy ();<br>}  <p>//bool ClientHandler::destroy () <br>//{<br>// FUNC_ENTER;<br>// ClientManager::get_instance().release_client_handle(this);<br>// FUNC_LEAVE;<br>// return false ;<br>//}  <p>int ClientHandler::initiate_read_stream (void)<br>{<br>ACE_Guard&lt;ACE_Recursive_Thread_Mutex&gt; locker (_lock);  <p>//考虑到粘包的呀<br>if (_rs.read (_read_msg_block, _read_msg_block.space()) == -1)<br>{<br>&nbsp;&nbsp; ACE_ERROR_RETURN ((LM_ERROR,"%p\n","ACE_Asynch_Read_Stream::read"),-1);<br>}<br>_io_count++;<br>return 0;<br>}  <p>/**生成一个写请求<br>*<br>* \param mb 待发送的数据<br>* \param nBytes 待发送数据大小<br>* \return 0－成功，－1失败<br>*/<br>int ClientHandler::initiate_write_stream (ACE_Message_Block &amp; mb, size_t nBytes )<br>{<br>ACE_Guard&lt;ACE_Recursive_Thread_Mutex&gt; locker (_lock);<br>if (_ws.write (mb , nBytes ) == -1)<br>{<br>&nbsp;&nbsp; mb.release ();<br>&nbsp;&nbsp; ACE_ERROR_RETURN((LM_ERROR,"%p\n","ACE_Asynch_Write_File::write"),-1);<br>}<br>_io_count++;<br>return 0;<br>}  <p>void ClientHandler::open (ACE_HANDLE handle,ACE_Message_Block &amp;message_block)<br>{<br>//FUNC_ENTER;<br>_last_net_io=ACE_OS::time(NULL);<br>_io_count=0;<br>if(_ws.open(*this,this-&gt;handle())==-1)<br>{<br>&nbsp;&nbsp; ACE_ERROR ((LM_ERROR,"%p\n","ACE_Asynch_Write_Stream::open"));<br>}<br>else if (_rs.open (*this, this-&gt;handle()) == -1)<br>{<br>&nbsp;&nbsp; ACE_ERROR ((LM_ERROR,"%p\n","ACE_Asynch_Read_Stream::open"));<br>}<br>else<br>{<br>&nbsp;&nbsp; initiate_read_stream ();<br>}  <p>check_destroy();<br>//FUNC_LEAVE;<br>}  <p>void ClientHandler::fini()<br>{<br>}  <p>void ClientHandler::check_time_out(time_t cur_time)<br>{<br>//ACE_Guard&lt;ACE_Recursive_Thread_Mutex&gt; locker (_lock);<br>//ACE_DEBUG((LM_DEBUG,"cur_time is %u,last io is %u\n",cur_time,_last_net_io));  <p>//检测是否已经为0了<br>if(this-&gt;handle()==ACE_INVALID_HANDLE)<br>&nbsp;&nbsp; return;<br>if(cur_time-_last_net_io&gt;CLIENT_TIME_OUT_SECONDS)<br>{<br>&nbsp;&nbsp; ACE_OS::shutdown(this-&gt;handle(),SD_BOTH);<br>&nbsp;&nbsp; ACE_OS::closesocket(this-&gt;handle());<br>&nbsp;&nbsp; this-&gt;handle(ACE_INVALID_HANDLE);<br>}<br>}  <p>int ClientHandler::check_destroy()<br>{<br>{<br>&nbsp;&nbsp; ACE_Guard&lt;ACE_Recursive_Thread_Mutex&gt; locker (_lock);<br>&nbsp;&nbsp; if (_io_count&gt; 0)<br>&nbsp;&nbsp;&nbsp; return 1;<br>}<br>ACE_OS::shutdown(this-&gt;handle(),SD_BOTH);<br>ACE_OS::closesocket(this-&gt;handle());<br>this-&gt;handle(ACE_INVALID_HANDLE);  <p>//这个地方给内存池吧。<br>ClientManager::get_instance().release_client_handle(this);<br>//delete this;<br>return 0;<br>}</p><img src ="http://www.cppblog.com/woaidongmao/aggbug/47533.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-04-18 20:47 <a href="http://www.cppblog.com/woaidongmao/archive/2008/04/18/47533.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows 发邮件的方案</title><link>http://www.cppblog.com/woaidongmao/archive/2008/04/16/47323.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Wed, 16 Apr 2008 13:25:00 GMT</pubDate><guid>http://www.cppblog.com/woaidongmao/archive/2008/04/16/47323.html</guid><wfw:comment>http://www.cppblog.com/woaidongmao/comments/47323.html</wfw:comment><comments>http://www.cppblog.com/woaidongmao/archive/2008/04/16/47323.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/woaidongmao/comments/commentRss/47323.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/woaidongmao/services/trackbacks/47323.html</trackback:ping><description><![CDATA[<h3>SMTP协议，<a href="http://www.w3school.com.cn/media/media_mimeref.asp">MIME</a>协议</h3> <h3>INFO： MAPI 是不适用于 HTML 邮件</h3> <p>扩展邮件应用编程接口 (MAPI) 应该不是用于生成 HTML 格式的邮件。 作为备用方案, 考虑使用 Microsoft Outlook 对象模型、 CDONTS、 CDOSYS， CDOEX 或第三方 SMTP 控件。  <p><a href="http://support.microsoft.com/#top"><img alt="" src="http://support.microsoft.com/library/images/support/en-us/uparrow.gif">回到顶端</a>  <h4>更多信息</h4> <p>MAPI 1.0 写入 HTML 邮件开发并不可靠支持创建 HTML 格式邮件之前。 MAPI 1.0 是由所有版本的 MicrosoftExchange 版本 5.5 通过支持版本 (和所有 ServicePack）。 这包括以下从属技术：  <p>•<br>简单 MAPI  <p>•<br>扩展 MAPI  <p>•<br>OLE 消息  <p>•<br>活动消息 （协作数据对象 (CDO) 1.1）  <p>•<br>CDO 1.21 1.2 和版本  <p>•<br>MAPI 控件 (Msmapi32.ocx)  <p>如果邮件以 HTML 格式, 需要如用于发送其他语言, 中文字其他技术提供更可靠支持对 HTML 邮件建议：  <p><font color="#ff0000">•</font>  <p><font color="#ff0000">JMail </font> <p><font color="#ff0000">•<br>CDONTS</font>  <p><font color="#ff0000">•<br>CDO for Windows 2000 (CDOSYS)</font>  <p><font color="#ff0000">•<br>CDO for Exchange 2000 (CDOEX)</font>  <p><font color="#ff0000">•<br>Outlook 对象模型的 Microsoft Outlook 98 或更高版本</font>  <p><font color="#ff0000">•<br>从第三方供应商获取支持 SMTP - ActiveX 控件</font>  <p><a href="http://support.microsoft.com/#top"><img alt="" src="http://support.microsoft.com/library/images/support/en-us/uparrow.gif">回到顶端</a>  <h5>Outlook 如何生成基于 MAPI 的 HTML 邮件</h5>除为通过 HTMLBody 属性公开什么接口， Outlook 用来生成和使用 HTML 格式邮件是不公开外部。 Outlook 将 HTML 数据存储作为特殊编码 RTF 流 PR_RTF_COMPRESSED MAPI 属性中。 有任何公共接口用于生成、 读取, 或操作此复杂流作为 HTML 数据。 PR _ BODY 包含邮件正文的纯文本转换。  <h6>PR_BODY_HTML 呢 ？</h6>如果 PR_STORE_SUPPORT_MASK 属性中存储返回 STORE_HTML_OK 根据文档 PR_BODY_HTML, 上此属性仅支持由邮件存储。 没有 Microsoft 邮件存储支持此标志。 某些第三方存储提供程序可能选择将支持此标记和属性。  <img src ="http://www.cppblog.com/woaidongmao/aggbug/47323.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/woaidongmao/" target="_blank">肥仔</a> 2008-04-16 21:25 <a href="http://www.cppblog.com/woaidongmao/archive/2008/04/16/47323.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>