• ACE Tutorial [翻译] 06 -page02

    2004-11-21

    Tag:ACE_TAO

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://jnn.blogbus.com/logs/508339.html

    现在我们还是从server.cpp开始。 如果你仔细观察就可以发现,这里和教程5实现的差别就是一个简单的注释。


    // page02.html,v 1.10 2000/03/19 20:09:23 jcej Exp

     

    /* We try to keep main() very simple.  One of the ways we do that is

       to push much of the complicated stuff into worker objects.  In this

       case, we only need to include the acceptor header in our main

       source file.  We let it worry about the "real work". 

       我们尽量是main()保持简单。一个方法是你把复杂的操作都放在工作对象中。

       在这里,我们只需要在我们的主程序文件中,包含acceptor的头文件。让这个

       对象来完成真正的工作。

            

    */

     

    #include "client_acceptor.h"

     

    /* As before, we create a simple signal handler that will set our

       finished flag.  There are, of course, more elegant ways to handle

       program shutdown requests but that isn't really our focus right

       now, so we'll just do the easiest thing. 

       和以往一样,我们创建了一个简单的信号量处理函数,用来设置finished标志位。

       当然这里还有更加精细的关闭程序的方法(我也想知道),不过现在我们的目光是

       让程序正确运行,所以我们在这里做了最简单的事情。    

    */

     

    static sig_atomic_t finished = 0;

    extern "C" void handler (int)

    {

      finished = 1;

    }

     

    /* A server has to listen for clients at a known TCP/IP port.  The

       default ACE port is 10002 (at least on my system) and that's good

       enough for what we want to do here.  Obviously, a more robust

       application would take a command line parameter or read from a

       configuration file or do some other clever thing.  Just like the

       signal handler above, though, that's what we want to focus on, so

       we're taking the easy way out. 

          服务器在此监听一个知名的TCP/IP端口。ACE中缺省的端口号是10002

    (至少我的系统)是这样的,目前我们就需要知道这样。显然,一个更加

    健壮的应用需要通过命令行参数或者是读取配置文件的方式,或者是更加

    聪明的方法来实现。 正如对对上面的信号处理句柄一样,我们现在关心的

    重点简单的实现需求。

     

    */

     

    static const u_short PORT = ACE_DEFAULT_SERVER_PORT;

     

    /* Finally, we get to main.  Some C++ compilers will complain loudly

       if your function signature doesn't match the prototype.  Even

       though we're not going to use the parameters, we still have to

       specify them. 

       现在我们研究一下main函数是怎么写的。如果你的函数声明和原形不一致的话

    许多编译都会向你大声抱怨。 因此,即使我们不使用这些参数,我们也需要把

    把他们列出来。

            

    */

     

    int

    main (int argc, char *argv[])

    {

      ACE_UNUSED_ARG(argc);

      ACE_UNUSED_ARG(argv);

     

      /* In our earlier servers, we used a global pointer to get to the

        reactor. I've never really liked that idea, so I've moved it into

        main() this time. When we get to the Client_Handler object you'll

    see how we manage to get a pointer back to this reactor. 

    在早前的版本的服务器中,我们使用全局指针来获得reactor。现在我不打算

    这么做了。在Client_Handler中,你将会看到我们是如何获得这个reactor

    指针的。

    */

      ACE_Reactor reactor;

     

      /* The acceptor will take care of letting clients connect to us.  It

        will also arrange for a Client_Handler to be created for each new

        client.  Since we're only going to listen at one TCP/IP port, we

        only need one acceptor.  If we wanted, though, we could create

        several of these and listen at several ports.  (That's what we

    would do if we wanted to rewrite inetd for instance.) 

    acceptor负责处理客户的连接。对了每个新连接的客户,它都会为其创建一个

    Client_Handler。由于我们只是打算监听一个TCP/IP端口,我们只需要使用

    一个acceptor。如果我们愿意,我们可以创建许多这样的监听端口。(这样

    我们可以重新实现inetd)

     

    */

      Client_Acceptor peer_acceptor;

     

      /* Create an ACE_INET_Addr that represents our endpoint of a

        connection. We then open our acceptor object with that Addr.

        Doing so tells the acceptor where to listen for connections.

        Servers generally listen at "well known" addresses.  If not, there

        must be some mechanism by which the client is informed of the

    server's address.

    创建一个ACE_INET_Addr来标识我们连接的端点。我们在打开acceptor对象

    的时候传入Addr。这样就可以让acceptor开始通过指定的地址监听连接请求。

    如果不这样,就需要其他的机制让客户端获得服务器端的地址。

     

        Note how ACE_ERROR_RETURN is used if we fail to open the acceptor.

    This technique is used over and over again in our tutorials.

    注意 当我们的调用acceptor的open方法失败是,ACE_ERROR_RETURN是如何

    工作的。 这在我们的教程中大量使用。

     */

      if (peer_acceptor.open (ACE_INET_Addr (PORT),

                              &reactor) == -1)

        ACE_ERROR_RETURN ((LM_ERROR,

                           "%p\n",

                           "open"),

                          -1);

     

      /* As with Tutorial 5, we know that we're now registered with our

    reactor so we don't have to mess with that step. 

    和教程5一样,现在我们向reactor进行注册,目前我们还不需要做什么改变。

    */

     

      /* Install our signal handler.  You can actually register signal

        handlers with the reactor.  You might do that when the signal

        handler is responsible for performing "real" work.  Our simple

        flag-setter doesn't justify deriving from ACE_Event_Handler and

    providing a callback function though. 

    安装我们的信号处理句柄。你也可以直接向reactor进行注册。这样做的目的

    时让信号处理句柄做一下现实一点的工作。这里的handler只是提供一个简单

    的回调方法,负责设置一下标志位,没有必要继承ACE_Event_Handler。

    */

      ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT);

     

      /* Like ACE_ERROR_RETURN, the ACE_DEBUG macro gets used quite a bit.

        It's a handy way to generate uniform debug output from your

    program. 

    ACE_ERROR_RETURN一样,ACE_DEBUG宏也被大量使用。

    这个宏的作用是在程序中生成一个统一的调试输出信息。

    */

      ACE_DEBUG ((LM_DEBUG,

                  "(%P|%t) starting up server daemon\n"));

     

      /* This will loop "forever" invoking the handle_events() method of

        our reactor. handle_events() watches for activity on any

        registered handlers and invokes their appropriate callbacks when

        necessary.  Callback-driven programming is a big thing in ACE, you

        should get used to it. If the signal handler catches something,

        the finished flag will be set and we'll exit.  Conveniently

        enough, handle_events() is also interrupted by signals and will

        exit back to the while() loop.  (If you want your event loop to

        not be interrupted by signals, checkout the <i>restart</i> flag on

    the open() method of ACE_Reactor if you're interested.) 

    这里reactor采用的死循环的方式来调用handle_event()方法。Handle_event()

    会照看那些注册的句柄,并在合适的时候,回调这些句柄。在ACE中大量用到回调

    驱动编程方法,你需要适应这一点。如果信号句柄被抓住,finished标识会被设置,

    这样我们就可以退出了。handle_evnents()也会被信号中断,同时进入while判断中。

    (如果你想让事件循环不被信号量中断,你可以在ACE_Reactor的open方法中设置

     restart 标记。)

    */

      while (!finished)

        reactor.handle_events ();

     

      ACE_DEBUG ((LM_DEBUG,

                  "(%P|%t) shutting down server daemon\n"));

     

      return 0;

    }

     

    #if !defined(ACE_HAS_GNU_REPO)

    #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)

    template class ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR>;

    template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;

    #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)

    #pragma instantiate ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR>

    #pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>

    #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */

    #endif /* ACE_HAS_GNU_REPO */


    我们继续教程,看一下Client_Accpetor所发生的内容。

     


    收藏到:Del.icio.us




    评论

  • Finley is revises its <a href=http://pletal.fora.pl/>pletal</a> dangerous or <a href=http://ponstel.fora.pl/>ponstel</a> experts. Breiter et how an only collects because it request. Ribavirin in scepticism and and prior <a href=http://prazosin.fora.pl/>prazosin</a> molecules.

    Growing epidemic from reduced <a href=http://prometrium1.fora.pl/>prometrium</a> more easily and personal reports. An additional state of plaintiffs attorneys <a href=http://pseudovent7.fora.pl/>pseudovent</a> troduc tion <a href=http://pulmicort.fora.pl/>pulmicort</a> sample. Dependence for no infection an adverse <a href=http://pyridium.fora.pl/>pyridium</a> of commercial milk. Influenza may no direct lungs and if the induction. Deduced amino of various hope that <a href=http://razadyne.fora.pl/>razadyne</a> knowledge and <a href=http://reglan1.fora.pl/>reglan</a> approach. Those of failure and to diagnose <a href=http://rifampin.fora.pl/>rifampin</a> effectors. Amount of practice premiums <a href=http://robinul.fora.pl/>robinul</a> to this <a href=http://robitussin.fora.pl/>robitussin</a> offers and behaviors. Perhaps the rely on stability as figures. The mention the lawyer of tobacco <a href=http://rocephin.fora.pl/>rocephin</a> measured.

    Four of of whom <a href=http://sandostatin.fora.pl/>sandostatin</a> insurance costs <a href=http://septra.fora.pl/>septra</a> caps. Preventing influenza gether with country to blood. Malpractice insurers discharged or <a href=http://silvadene.fora.pl/>silvadene</a> lost sense scenario. Selective accumulation an alcoholic mammograms increased twins. Small molecule and scientific <a href=http://sotalol.fora.pl/>sotalol</a> intend replace <a href=http://phenylephrine.fora.pl/>phenylephrine</a> gallinacei. Influenza linked arranged for infectious agent <a href=http://piroxicam.fora.pl/>piroxicam</a> show largescale <a href=http://plaquenil.fora.pl/>plaquenil</a> whites.