ACE Tutorial [翻译] 01-page02 :: 风之谷
来源: BlogBus 原始链接: http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=459164 存档链接: https://web.archive.org/web/20041029160746id_/http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=459164
风之谷 有关ACE/TAO,还有CORBA的学习资料 <<<ACE Tutorial [翻译]01-page01 | 首页 | ACE Tutorial [翻译] 01-page03>>> ACE Tutorial [翻译] 01-page02 时间:2004-10-24 从现在开始,我们将把目光集中在主循环程序中。虽然这段代码是我们最后的实现产品,但是由于这段代码很简单,因此是一个比较好的入手点。 因为大量的时间工作是由 ACE 的派生类来实现的,所以主程序的确特别简单。 Kirthika Parameswaran 提供了对教程 1 的简要描述: 这是一个简单的日志服务器例子。 Reactor 采用单线程而不是一个客户一个线程方式,实现了的多个客户的请求处理。 Reactor 负责响应事件,并通过“ callback ”技术将事件转发到注册了该事件的 Event_Handler 。 Reactor 在一个死循环中运行,用以响应所有的到来的事件。 Logging_Acceptor 监听一个叫做 SERVER PORT 的网络地址,并被动地接收到来的请求。这个 Acceptor 也是一个注册到 Reactor 上的 Event_Handler 。对于 Reactor 来说,这只是又一个简单的 Event_Handler ,不需要对其进行特别的处理。 一旦客户连接事件发生, Acceptor 会接受客户连接并且为此建立一个连接。这里需要一个监听处理句柄会向 Reactor 进行注册,并且需要使用一个 ACE_Event_Handler::ACCEPT_MASK 掩码 . Logging_Client 是用以处理客户请求的一个 Event_Handler ,它通过 hanlde_input() 方法来处理与用户的交互。它使用 ACE_Event_Handler::READ_MASK 向 Reactor 进行注册。 Event_Handler 可以通过 handle_close() 方法或者显示调用 remove_handler() 向 Reactor 注销。 编译完服务应用,并运行,程序就循环等待客户请求的到达。 FYI (from Doug): ACCEPT_MASK 是在 ACE_Event_Handler 类中所定义的掩码。它负责向 Reactor 通知,和它一起注册的事件处理句柄希望被动的接收连接请求。一般情况下, ACE_Acceptor 使用这个掩码。 READ_MASK 也是 ACE_Event_Handler 类中所定义的掩码。它负责向 Reactor 通知,和它一起注册的事件处理句柄希望从一个建立好的连接中读取数据。 // page02.html,v 1.14 2000/03/19 20:09:19 jcej Exp /* 包含client acceptor所定义的头文件 / #include " ace/Reactor.h " / For simplicity, we create our reactor in the global address space. In later tutorials we will do something more clever and appropriate. However, the purpose of this tutorial is to introduce a connection acceptance and handling, not the full capabilities of a reactor. 简单来说,在全局空间里面创建了一个reactor。在后面的教程中, 讲介绍更加合适和聪明的方法,来创建 reactor。由于本教程的目标是为了 介绍如何建立连接和处理连接的,所以没有涉及更多的有关 reactor部分 的内容。 */ ACE_Reactor g_reactor; / Include the header where we define our acceptor object. An acceptor is an abstraction that allows a server to " accept " connections from clients. */ /包含了我们的acceptor对象的头文件,acceptor对象是一个能够让 服务器“接收”客户连接请求抽象类 / #include " acceptor.h " / A TCP/IP server can listen to only one port for connection requests. Well-known services can always be found at the same address. Lesser-known services are generally told where to listen by a configuration file or command-line parameter. For this example, we're satisfied with simply hard-coding a random but known value. / / 一个TCP/IP服务器只能监听一个连接请求端口。著名的服务所监听的端口都是一样的。 而其他的服务一般通过读取配置文件或者是命令行的方式来实现对端口的监听。 在这个例子中我们使用直接在程序中指定的方法来实现(产生随机指定的端口) / static const u_short PORT = ACE_DEFAULT_SERVER_PORT; int main (int, char []) { / Create a Reactor instance. Again, a global pointer isn't exactly the best way to handle this but for the simple example here, it will be OK. We'll get cute with it later. Note how we use the ACE_NEW_RETURN macro, which returns 1 if operator new fails. / / 创建一个Reactor实例。再次声明,全局指针不是一个创建Reactor最好的办法。 教程里面是为了简化操作,才这么写是的。在后面的教程里面我们将把这段代码删除。 注意我们在这使用了 ACE_NEW_RETURN ,当new操作失败,这个宏会返回1/ ACE_NEW_RETURN (g_reactor, ACE_Reactor, 1); / Like the Reactor, I'm skimming over the details of the ADDR object. What it provides is an abstraction for addressing services in the network. All we need to know at this point is that we are creating an address object which specifies the TCP/IP port on which the server will listen for new connection requests. */ /和Reactor一样,我们将跳过ADDR对象的细节。它提供了一个对网络 地址的抽象。目前只需要知道我们创建的是一个指定 TCP/IP端口的地址 对象。我们的服务器通过这个端口用来监听新的连接请求。 / ACE_INET_Addr addr (PORT); Logging_Acceptor peer_acceptor; / We now create an acceptor object. No connections will yet be established because the object isn't " open for business " at this time. Which brings us to the next line... / / 我们现在来创建acceptor对象。 由于它现在还没有“开张”,因此还不 能建立任何连接。有关“开张”的代码将会在下一行出现 / ACE_NEW_RETURN (peer_acceptor, Logging_Acceptor, 1); / where the acceptor object is opened. You'll find that most ACE objects have to be open()ed before they're of any use to you. On this open() call, we're telling the acceptor where to listen for connections via the 'addr' object. We're also telling it that we want it to be registered with our 'g_reactor' instance. / / 这段代码调用了acceptor对象的open方法。你会发现大多数的ACE 对象在正式使用之前,都会调用 open()方法。在open方法中, 我们将告知 acceptor去监听那个 “addr”对象。我们同时告知acceptor 将会被注册到我们的“ g_reactor”实例上/ if (peer_acceptor->open (addr, g_reactor) == -1 ) ACE_ERROR_RETURN ((LM_ERROR, " Opening Acceptor\n "), -1); ACE_DEBUG ((LM_DEBUG, " (%P|%t) starting up server logging daemon\n ")); / The reactor's handle_events member function is responsible for looking at all registered objects and invoking an appropriate member function when anything of interest occurs. When an event is processed, the handle_events function returns. In order to get all events, we embed this in an infinite loop. Since we put ourselves into an infinite loop, you'll need to CTRL-C to exit the program. / / Reactor的handle_events方法是负责查找所有的注册对象,并且当这些 对象所感兴趣的事件发生时,调用这些对象的确定的方法。当事件处理完毕, handle_event方法返回。为了能够处理所有的事件,handle_event方法被放 置在一个死循环中 虽然程序是处于死循环的状态中,但是你可以通过CTRL-C来退出程序。 */ for (;;) g_reactor->handle_events (); return 0; } 正如前面说讲,这个主程序的确很简单 创建一个 address 对象,指定的我们所希望监听的端口。 创建一个 acceptor ,用来监听指定的 address 。 向 Reactor 注册 acceptor ,来响应连接请求。 进入一个死循环,让 reactor 来负责响应事件。 在下一页中,我们将详细介绍 acceptor ,看一下它是如何响应新的连接请求的。 jnn 发表于 2004-10-24 23:55 引用Trackback(0) | 编辑 评论 发表评论 最后更新 ACE Tutorial [翻译] 04 ACE Tutorial [翻译] 03 ACE Tutorial [翻译] 02-page03 ACE Tutorial [翻译] 02-page02 ACE Tutorial [翻译] 02-page01 ACE Tutorial [翻译] 01-page04 ACE Tutorial [翻译] 01-page03 ACE Tutorial [翻译] 01-page02 ACE Tutorial [翻译]01-page01 ACE 教程 [翻译] (前言)