// 複数クライアントを同時に取り扱えるデーモンの例 #include #include #include #include #include #include #include "integnet.h" // 接続先のポート #define PORT 12345 // 子プロセスが終了すると呼び出されるシグナルハンドラ void Wait( int ) { // 終了したすべての子プロセスの回収 while( waitpid(-1,NULL,WNOHANG) > 0 ); // シグナルハンドラの再設定 signal( SIGCHLD, Wait ); } int main( void ) { int sb = socket( AF_INET, SOCK_STREAM, 0 ); sockaddr_in addr = SOCKADDR_IN_INIT( AF_INET, htons(PORT), InAddr(htonl(INADDR_ANY)) ); if( bind( sb, (sockaddr*)&addr, sizeof(addr) ) < 0 ){ perror("bind"); exit(1); } // 最大同時4回線の接続を許可する設定 listen( sb, 4 ); // 子プロセスの終了時にシグナルハンドラが動くように設定 signal( SIGCHLD, Wait ); // サーバーループ while(1){ int s; // acceptで待機、エラーの場合はループ冒頭に戻る if( (s=accept( sb, NULL, NULL )) < 0 ) continue; // 子プロセスを作る if( fork() ){ //---- 親プロセスの作業 close(s); // クライアントへのソケットは要らない continue; // ループ冒頭に戻る } //---- 子プロセスの作業 close(sb); // 基本ソケットは要らない // データの受信と送信 char rmsg[64], smsg[64]; int len; len = recv( s, rmsg, sizeof(rmsg), 0 ); rmsg[len] = '\0'; len = snprintf( smsg, sizeof(smsg), "Server recv: %s", rmsg ); len = send( s, smsg, len, 0 ); close(s); exit(0); // 子プロセスはここで終了 } close(sb); return 0; }