- 締切済み
サーバプログラム
C言語の初心者です。 OS : CentOS 5.3 c言語でサーバ用のプログラムを書きました。 ソケット通信で接続してきたクライアントにデータをそのまま返すと言うものです。 コンパイルしたソースが、 gcc -Wall -o example example.c だとすると、この exampleソースを サービスとして( 「デーモンとして」と言うのか? )、起動したい場合、 どのように起動すればよいのでしょうか? ./example と叩くだけだと、叩いた間だけしかプログラムは動いてくれませんよねぇ。 また、サーバプログラムの良書を教えていただけたら幸いです。 初歩的な事でしたら申し訳ないですが、 よろしくお願いします。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- dev_null
- ベストアンサー率67% (37/55)
> どちらが仕事として運用する方法として、正しいのでしょうか? 業務で使用するなら「コマンドを..」という方法だった場合、 及第点はあげられません。 コマンドを直接起動して問題が発生する可能性も考えられますし、 複数の接続先から同時にアクセスがあった場合などを考えても、 拡張性が劣ることが理由です。 自分は、下記の書籍を枕の下に置いてました。 「UNIXネットワークプログラミング」 「詳解TCP / IP」
- dev_null
- ベストアンサー率67% (37/55)
brosis様のとった方法は、solaris9様の参考サイトにある 「コマンドをデーモンプロセスのように動作させる」という方法になります。 デーモンプロセスとは、「デーモンプロセスプログラミング」のような手順 を踏んだプログラムを差すのではないでしょうか。 コマンドをデーモンとして動かすのなら nohup コマンドも参照してください。
お礼
dev_null様 ご回答ありがとうございます。 「コマンドをデーモンプロセスのように動作させる」という方法 と「デーモンプロセスプログラミング」のような手順を踏んだプログラム。 あまりはっきり意味を理解できていないのですが、 どちらが仕事として運用する方法として、正しいのでしょうか?
- solaris9
- ベストアンサー率66% (6/9)
以下のサイトが参考になると思います。 http://www7a.biglobe.ne.jp/~tsuneoka/daemon/ http://ja.wikipedia.org/wiki/%E3%83%87%E3%83%BC%E3%83%A2%E3%83%B3_(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2)
お礼
早速のご回答ありがとうございます。 私の方で、下記のサイトを見つけ 一応プログラムを常駐させることができました。が、 solaris9さんが教えてくれたサイト http://www7a.biglobe.ne.jp/~tsuneoka/daemon/ と、私の見つけたサイトのやっていることは同じ事なんでしょうか? すみません、初心者すぎて。
補足
すみません。 「下記のサイト」とは↓です。 http://7ujm.net/linux/daemon.html また、シグナルに関してですが。 solaris9さんが教えてくれたサイトには、 シグナル 「SIGCHLDをSIG_IGNとするだけで対処できます」とありますが、 実際、私のソースにも↓の init_signal()関数の中で、↓ int main( void ) { struct sockaddr_in sin; /* サーバソケットの初期化 */ listen_fd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ); if( listen_fd < 0 ) { fprintf( stderr, "Failed to create Server socket.\n" ); exit( EXIT_FAILURE ); } memset( &sin, 0, sizeof( sin ) ); sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons( 7777 ); if( bind( listen_fd, (struct sockaddr *)&sin, sizeof( sin ) ) < 0 ) { fprintf( stderr, "Failed to bind Server socket.\n" ); goto error; } if( listen( listen_fd, SOMAXCONN ) < 0 ) { fprintf( stderr, "Failed to listen Client socket.\n" ); goto error; } printf( "Server listening port %d...\n", 7777 ); /* シグナル処理関数の初期化 関数 */ init_signal(); /* クライアントのアクセス待ち 関数 */ access_loop(); error: close( listen_fd ); exit( EXIT_SUCCESS ); } void init_signal( void ) { signal( SIGINT, close_server_fd ); signal( SIGTERM, close_server_fd ); signal( SIGCHLD, wait_child ); /* 子プロセス終了時→wait_child */ return; } というように SIGCHLD を書いていますが。 fork()をするのは、↑のmain関数後半のaccess_loop()関数内です。 クライアントからの接続要求あったことを確認した後です。 solaris9さんが教えてくれたサイトにある、 リスト4 初期化処理の例 で書かれている、 /* 不要なシグナルを禁止する */ signal(SIGALRM, SIG_IGN); signal(SIGCHLD, SIG_IGN); /* ゾンビ止め */ signal(SIGHUP , SIG_IGN); signal(SIGPIPE, SIG_IGN); signal(SIGTERM, SIG_IGN); とは役割・意味合いが違うのでしょうか? 説明が分かりにくかったら申し訳ないです。
お礼
再びありがとうございます。 >コマンドを直接起動して問題が発生する可能性も考えられますし、 >複数の接続先から同時にアクセスがあった場合などを考えても、 >拡張性が劣ることが理由です。 難しいですねぇ。具体的にどんな問題なのか、想像できません。 ご紹介頂いた本を理解すれば、想像がつくのでしょうか。