ACE Tutorial 001
初心者のための ACE ツールキットガイド


ここからはメインのプログラムループに入ろう。 これは作っていった最終版のコードであるが、単純なものなのでこれから着手するにはちょうどいいだろう。

The main main のプログラムはいたって単純である。 実際の作業は ACE から派生したクラスが行う。

Kirthika Parameswaran はチュートリアル1の概要を次のように述べている。

参考情報(from Doug):
// $Id$

/* acceptor が定義されているヘッダをインクルード */
#include "ace/Reactor.h"


/*
  単純化のためリアクタをグローバルに定義する。
  以降のチュートリアルではもっと賢く適切な方法を取っている。
  しかし、このチュートリアルでは接続の受諾とハンドリングを紹介するため
  リアクタの全能力を使ってはいない。
*/

ACE_Reactor *g_reactor;


/*
  Acceptor オブジェクトの定義を取り込むためヘッダをインクルードする。
  Acceptor はサーバがクライアントからの接続依頼を accept するための
  処理を抽象化する。
*/

#include "acceptor.h"


/*
  TCP/IP サーバは接続要求待ちのために一つのポート(のみ)を監視できる。
  よく知られた(有名な)サービスは常に同じポートアドレスを利用する。
  あまり知られていないサービスの場合は設定ファイルやコマンドラインから
  受け付けるポート番号を指定される。
  この例では単純に適当な値をハードコーディングしておく。
*/

static const u_short PORT = ACE_DEFAULT_SERVER_PORT;

int
main (int, char *[])
{
  
  /*
    Reactor のインスタンスを作成する。
    繰り返すが、本来はグローバルポインタを利用するのは良い方法ではない。
    今回の例では単純性を重視する目的でこのような方法をとった。
    後から、もっとちゃんとした方法を紹介する。
    なお、ここで new が失敗した時に1を返す目的で利用している ACE_NEW_RETURN
    マクロの用法を覚えておくと良いだろう。
  */

  ACE_NEW_RETURN (g_reactor,
                  ACE_Reactor,
                  1);

  
  /*
    Reactor と同様に ADDR オブジェクトの詳細も省くことにする。
    これはネットワークアドレスの取り扱いを抽象化するための方法を提供する。
    ここでは、サーバが接続を待つ TCP/IP ポート指定のためにアドレスオブジェクトを
    作成しているという事実のみ覚えておけば良い。
  */

  ACE_INET_Addr addr (PORT);

  Logging_Acceptor *peer_acceptor;

  
  /*
    ここで Acceptor オブジェクトを作成する。
    この時点ではまだ接続は確立されることはない。
    それは下の行の役目である。
  */

  ACE_NEW_RETURN (peer_acceptor,
                  Logging_Acceptor,
                  1);

  
  /*
    ここで Acceptor オブジェクトが開始される。
    大抵の ACE オブジェクトは本来の使用の際に open() 関数が呼ばれる。
    この open() 呼び出しにより 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"));

  
  /*
    Reactor の handle_events メンバ関数は、登録済みの全ての
    オブジェクトを監視し、何かのイベントが起きた時には適切な
    メンバ関数を呼ぶという責任を持つ。
    一つのイベントが処理されるたびに handle_events 関数からは処理が返る。
    全てのイベントを処理するために、ここでは無限ループを利用する。

    ここでは無限ループへ入ることにしたため、プログラム終了の際には
    Ctrl-C を押してやる必要がある。
  */


  for (;;)
    g_reactor->handle_events ();

  return 0;
}


この通り、メインプログラムは実にシンプルである。

次では acceptor について、それがどのように新規接続リクエストを処理するのか見ていく。


[インデックスへ] [次へ進む]