fork()を使ったマルチクライアント型プログラム
マルチクライアント型のサーバーを作成する場合、fork()システムコールを使って プロセスを分けて しまうこともできます。つまり、親プロセスではクライアントからの接続要求 だけを処理し、実際のクライアントの処理は子プロセスに任せてしまうのです。 今回の並行サーバーのプログラムには、
if ((pid = fork()) < 0) { perror("fork"); exit(1); } else if (pid == 0) { /* fork()で新しく生成されたプロセスはこちら */ close(fd1); ret = read(fd2, buf, 1024); while (strcmp(buf, "quit\n") != 0) { /* bufの中の小文字を大文字に変換する */ for (i=0; i< ret; i++) { if (isalpha(buf[i])) buf[i] = toupper(buf[i]); } /* 変換したデータをクライアントに送り返す */ write(fd2, buf, 1024); ret = read(fd2, buf, 1024); } exit(0); }という処理が追加されています。 このプログラムでは、acceptシステムコールによりクライアントからの接続要 求を受け入れると、まずfork()システムコールを実行します。fork()システム コールの返り値が負の数ならば、失敗しているので終了します。
fork()システムコールの返り値(pidの値)が0となるのは、子プロセスの場合で す。子プロセスでは、クライアントからの接続を受け入れるためのファイルディ スクリプタfd1をクローズします。これは、子プロセスでは新たな接続要求を 受け付けないためです。そして、accect()システムコールにより返された、クラ イアントと接続されているファイルディスクリプタを用いて、大文字への変換 作業を行います。
一方、親プロセスでは、fork()システムコールから返ってきた直後にfd2をク ローズします。このファイルディスクリプタに関しては、子プロセスに処理を 依頼しており、親プロセス自身で処理する必要がないためです。その後、ルー プの先頭に戻り、再度accept()システムコールを実行して、別のクライアント が接続してくるのを待ちます。
クライアントプログラムは、これまでに使ってきた、iclient.c とまったく同じです。
![]()
![]()
![]()