﻿<?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++博客-宝杉的博客-随笔分类-ACE/CORBA</title><link>http://www.cppblog.com/robinson119/category/4148.html</link><description>UNIX/LINUX;ACE;SNMP;C++</description><language>zh-cn</language><lastBuildDate>Sat, 24 May 2008 16:25:26 GMT</lastBuildDate><pubDate>Sat, 24 May 2008 16:25:26 GMT</pubDate><ttl>60</ttl><item><title>【译】ACE Reactor 的设计和使用</title><link>http://www.cppblog.com/robinson119/archive/2007/08/03/29265.html</link><dc:creator>宝杉</dc:creator><author>宝杉</author><pubDate>Fri, 03 Aug 2007 04:42:00 GMT</pubDate><guid>http://www.cppblog.com/robinson119/archive/2007/08/03/29265.html</guid><wfw:comment>http://www.cppblog.com/robinson119/comments/29265.html</wfw:comment><comments>http://www.cppblog.com/robinson119/archive/2007/08/03/29265.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/robinson119/comments/commentRss/29265.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/robinson119/services/trackbacks/29265.html</trackback:ping><description><![CDATA[&nbsp;
<p style="FONT-SIZE: 10pt">1 介绍</p>
<p style="FONT-SIZE: 10pt">此文描述了组成ACE框架的Reactor模式的设计和执行。Reactor负责处理由一个或多个client并发的传递给一个应用程序的服务请求。应用程序的每个服务由一个分离的event handler（事件句柄）执行，event handler包括一个或多个进程的服务器特殊请求的方法。</p>
<p style="FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 此文描述的Reactor模式的执行，event handler分发是由ACE_Reactor实现的。ACE_Reactor结合I/O事件的分离器，以及其他类型的时间，比如timers和signals。ACE_Reactor的核心实现是基于同步事件分离，比如select或者WaitForMultipleObjects。当分离器指示指定的事件发生了，ACE_Reactor会自动分发预先注册的事件句柄的方法。注册的event handler方法会完成应用程序对应请求事件的服务。</p>
<p style="FONT-SIZE: 10pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 本文组织如下：第二章描述ACE_Reactor框架主要特性；第三章大致介绍ACE_Reactor实现的OO（面向对象）设计；第四章举了服务器端实现的例子，用以证明ACE_Reactor怎样简化并发的，基于事件的网络应用程序的发展；第五章描述当使用ACE_Reactor开发基于事件的应用程序的设计规则；第六章是结束语。</p>
<p style="FONT-SIZE: 10pt">2 ACE_Reactor的特性</p>
<p style="FONT-SIZE: 10pt">ACE_Reactor提供OO的事件分离机制和消息分发框架，它简化基于事件的应用程序的开发。以下特性是：</p>
<p style="FONT-SIZE: 10pt">OO的事件分离和消息分发接口：</p>
<p style="FONT-SIZE: 10pt">使用ACE_Reactor的应用程序不直接调用底层OS（操作系统）的事件分离API函数。比如select或WaitForMultipleObjects。他们继承ACE Event Handler基类并创建了具体的event handlers。这个类用特定的虚拟函数处理不同类型的事件，比如I/O事件，timer事件，signals（信号量机制），和同步事件。</p>
<p style="FONT-SIZE: 10pt">应用程序用Reactor框架创建具体的event handler，并注册他们。特性1显示了ACE Reactor.的关键组件。这个特性描述执行日子服务的事件句柄，这个在第四章讲述。<br><img style="WIDTH: 324px; HEIGHT: 311px" height=311 alt="" src="http://www.cppblog.com/images/cppblog_com/robinson119/reactor.jpg" width=324 border=0></p>
<img src ="http://www.cppblog.com/robinson119/aggbug/29265.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/robinson119/" target="_blank">宝杉</a> 2007-08-03 12:42 <a href="http://www.cppblog.com/robinson119/archive/2007/08/03/29265.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[原]ACE流--初学ACE</title><link>http://www.cppblog.com/robinson119/archive/2007/07/25/28745.html</link><dc:creator>宝杉</dc:creator><author>宝杉</author><pubDate>Wed, 25 Jul 2007 02:57:00 GMT</pubDate><guid>http://www.cppblog.com/robinson119/archive/2007/07/25/28745.html</guid><wfw:comment>http://www.cppblog.com/robinson119/comments/28745.html</wfw:comment><comments>http://www.cppblog.com/robinson119/archive/2007/07/25/28745.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/robinson119/comments/commentRss/28745.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/robinson119/services/trackbacks/28745.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ACE中的流包装提供面向连接的通信。流数据传输包装类包括ACE_SOCK_Stream和ACE_LSOCK_Stream，它们分别包装TCP/IP和UNIX域socket协议数据传输功能。连接建立类包括针对TCP/IP的ACE_SOCK_Connector和ACE_SOCK_Acceptor，以及针对UNIX域socket的ACE_LSOCK_Connector和ACE_LSOCK_Acceptor。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Acceptor类用于被动地接受连接（使用BSD accept()调用），而Connector类用于主动地建立连接（使用BSD connect()调用）。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下面的例子演示接收器和连接器是怎样用于建立连接的。该连接随后将用于使用流数据传输类来传输数据。</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><span style="FONT-SIZE: 14pt">server端代码：<br></span>// 环境VC6.0+ACE5.4.2<br>//&nbsp;proj:ACE stream server<br>//&nbsp;date:07-7-24<br>//&nbsp;robin<br>//</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">#include "stdafx.h"</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">#include "ace/Log_Msg.h"<br>#include "ace/Time_Value.h"<br>#include "ace/OS.h"</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><br>#include "ace/SOCK_Acceptor.h"<br>#include "ace/SOCK_Stream.h"</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">#define SIZE_DATA 18<br>#define SIZE_BUF 1024<br>#define NO_ITERATIONS 5</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">class Server<br>{<br>public:<br>&nbsp;Server (int port) : server_addr_(port),peer_acceptor_(server_addr_)<br>&nbsp;{<br>&nbsp;&nbsp;data_buf_ = new char[SIZE_BUF];<br>&nbsp;}</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;//Handle the connection once it has been established. Here the<br>&nbsp;//connection is handled by reading SIZE_DATA amount of data from the<br>&nbsp;//remote and then closing the connection stream down.</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;int handle_connection()<br>&nbsp;{<br>&nbsp;&nbsp;// Read data from client<br>&nbsp;&nbsp;for(int i=0;i&lt;NO_ITERATIONS;i++)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;int byte_count=0;<br>&nbsp;&nbsp;&nbsp;if( (byte_count = new_stream_.recv_n(data_buf_, SIZE_DATA, 0) ) == -1 )<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_ERROR ((LM_ERROR, "%p\n", "Error in recv"));<br>&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;data_buf_[byte_count]=0;<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_DEBUG((LM_DEBUG,"Server received %s \n",data_buf_));<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;// Close new endpoint<br>&nbsp;&nbsp;if (new_stream_.close () == -1)<br>&nbsp;&nbsp;&nbsp;ACE_ERROR ((LM_ERROR, "%p\n", "close"));<br>&nbsp;&nbsp;return 0;<br>&nbsp;}</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><br>&nbsp;//Use the acceptor component peer_acceptor_ to accept the connection<br>&nbsp;//into the underlying stream new_stream_. After the connection has been<br>&nbsp;//established call the handle_connection() method.<br>&nbsp;<br>&nbsp;int accept_connections ()<br>&nbsp;{<br>&nbsp;&nbsp;if (peer_acceptor_.get_local_addr (server_addr_) == -1)<br>&nbsp;&nbsp;&nbsp;ACE_ERROR_RETURN ((LM_ERROR,"%p\n","Error in get_local_addr"),1);<br>&nbsp;&nbsp;ACE_DEBUG ((LM_DEBUG,"Starting server at port %d\n",<br>&nbsp;&nbsp;&nbsp;server_addr_.get_port_number ()));<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;// Performs the iterative server activities.</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;while(1)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT);<br>&nbsp;&nbsp;&nbsp;if (peer_acceptor_.accept(new_stream_, &amp;client_addr_, &amp;timeout)== -1)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_ERROR ((LM_ERROR, "%p\n", "accept"));<br>&nbsp;&nbsp;&nbsp;&nbsp;continue;<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_DEBUG((LM_DEBUG,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Connection established with remote %s:%d\n",<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;client_addr_.get_host_name(),client_addr_.get_port_number()));</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;&nbsp;&nbsp;&nbsp;//Handle the connection<br>&nbsp;&nbsp;&nbsp;&nbsp;handle_connection();<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>&nbsp;}</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">private:<br>&nbsp;char *data_buf_;<br>&nbsp;ACE_INET_Addr server_addr_;<br>&nbsp;ACE_INET_Addr client_addr_;<br>&nbsp;ACE_SOCK_Acceptor peer_acceptor_;<br>&nbsp;ACE_SOCK_Stream new_stream_;<br>};</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><br>int main (int argc, char *argv[])<br>{<br>&nbsp;if(argc&lt;2)<br>&nbsp;{<br>&nbsp;&nbsp;ACE_ERROR((LM_ERROR,"Usage %s &lt;port_num&gt;", argv[0]));<br>&nbsp;&nbsp;ACE_OS::exit(1);<br>&nbsp;}</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">//&nbsp;char *ip;<br>//&nbsp;ip = new char[strlen("192.168.1.160")];<br>//&nbsp;Server server(ACE_OS::atoi(ip));&nbsp;&nbsp;//argv[1])</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;Server server(ACE_OS::atoi(argv[1]));<br>&nbsp;server.accept_connections();<br>&nbsp;return 0;<br>}<br><br><span style="FONT-SIZE: 18pt">client端：</span><br>//&nbsp;proj:ACE stream client<br>//&nbsp;client <br>//&nbsp;date:7-24<br>//&nbsp;robin</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">#include "stdafx.h"</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">//******additional*******//<br>#include "ace/Log_Msg.h"&nbsp;&nbsp;//ACE_ERROR&nbsp;ACE_DEBUG<br>#include "ace/Time_Value.h"&nbsp;&nbsp;// ACE_Time_Value<br>#include "ace/OS.h"&nbsp;&nbsp;&nbsp;&nbsp;// ACE_OS::atoi exit<br>//******additional*******//</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">#include "ace/SOCK_Connector.h"<br>#include "ace/INET_Addr.h"</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">#define SIZE_BUF 128<br>#define NO_ITERATIONS 5</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><br>class Client<br>{<br>public:<br>&nbsp;Client(char *hostname, int port):remote_addr_(port,hostname)<br>&nbsp;{<br>&nbsp;&nbsp;data_buf_="Hello from Client";<br>&nbsp;}</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;//Uses a connector component `connector_&#8217; to connect to a<br>&nbsp;//remote machine and pass the connection into a stream<br>&nbsp;//component client_stream_<br>&nbsp;int connect_to_server()<br>&nbsp;{<br>&nbsp;&nbsp;// Initiate blocking connection with server.<br>&nbsp;&nbsp;ACE_DEBUG ((LM_DEBUG, "(%P|%t) Starting connect to %s:%d\n",<br>&nbsp;&nbsp;&nbsp;remote_addr_.get_host_name(),remote_addr_.get_port_number()));<br>&nbsp;&nbsp;if (connector_.connect (client_stream_, remote_addr_) == -1)<br>&nbsp;&nbsp;&nbsp;ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) %p\n","connection failed"),-1);<br>&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;ACE_DEBUG ((LM_DEBUG,"(%P|%t) connected to %s\n",<br>&nbsp;&nbsp;&nbsp;remote_addr_.get_host_name ()));<br>&nbsp;&nbsp;return 0;<br>&nbsp;}</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><br>&nbsp;//Uses a stream component to send data to the remote host.<br>&nbsp;int send_to_server()<br>&nbsp;{<br>&nbsp;&nbsp;// Send data to server<br>&nbsp;&nbsp;for(int i=0;i&lt;NO_ITERATIONS; i++)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;if (client_stream_.send_n (data_buf_,<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_OS::strlen(data_buf_)+1, 0) == -1)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) %p\n","send_n"),0);<br>&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;//Close down the connection<br>&nbsp;&nbsp;close();<br>&nbsp;}</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;//Close down the connection properly.<br>&nbsp;int close()<br>&nbsp;{<br>&nbsp;&nbsp;if (client_stream_.close () == -1)<br>&nbsp;&nbsp;&nbsp;ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) %p\n","close"),-1);<br>&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;return 0;<br>&nbsp;}<br>private:<br>&nbsp;ACE_SOCK_Stream client_stream_;<br>&nbsp;ACE_INET_Addr remote_addr_;<br>&nbsp;ACE_SOCK_Connector connector_;<br>&nbsp;char *data_buf_;<br>};</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><br>int main(int argc, char* argv[])<br>{<br>&nbsp;if(argc&lt;3)<br>&nbsp;{<br>&nbsp;&nbsp;ACE_DEBUG((LM_DEBUG,"Usage %s &lt;hostname&gt; &lt;port_number&gt;\n", argv[0]));<br>&nbsp;&nbsp;ACE_OS::exit(1);<br>&nbsp;}</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">&nbsp;Client client(argv[1],ACE_OS::atoi(argv[2]));<br>&nbsp;client.connect_to_server();<br>&nbsp;client.send_to_server();<br>&nbsp;return 0;<br>}</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana"><br>运行结果：<br>cmd里到exe目录下，先启动服务端server.exe 192.168.1.160<br>如图1：<br><img style="WIDTH: 554px; HEIGHT: 121px" height=121 alt="" src="http://www.cppblog.com/images/cppblog_com/robinson119/server.JPG" width=554 border=0><br>正在轮询等待。<br><br>再到client服务端，同样的方法<br>运行命令行参数格式 client.exe 192.168.1.160 192<br>&nbsp;解析：ACE_DEBUG((LM_DEBUG,"Usage %s &lt;hostname&gt; &lt;port_number&gt;\n", argv[0]));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;命令行参数为 &lt;hostname&gt;&lt;port&gt; = &lt;192.168.1.160&gt;&lt;192&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;端口是由图1的第二行显示，不是自己设定的。<br>如图2：<br><img style="WIDTH: 557px; HEIGHT: 304px" height=304 alt="" src="http://www.cppblog.com/images/cppblog_com/robinson119/client.jpg" width=557 border=0></p>
<span style="FONT-SIZE: 10pt">只是照搬书上的例子，后面打算自己分析一下。</span> 
<img src ="http://www.cppblog.com/robinson119/aggbug/28745.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/robinson119/" target="_blank">宝杉</a> 2007-07-25 10:57 <a href="http://www.cppblog.com/robinson119/archive/2007/07/25/28745.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>