fork型並行サーバ Python socket module: Just a thin wrapper over the underlying C library's socket calls. fork型並行サーバ 並行サーバのセッションシーケンス 並行サーバと反復サーバの対比 並行サーバのプロセス作成 並行サーバのプログラムコードの特徴 TCPEchoServer-Fork.c main() int CreateTCPServerSocket(unsigned short port) int AcceptTCPConnection(int servSock) void HandleTCPClient(int clntSocket) fork型並行サーバPythonプログラム fork型並行サーバ 並行サーバのセッションシーケンス クライアント (接続要求) 並行サー バ servSock クライアント sock connect(sock,…) クライアント sock (接続) サーバ accept(servSock,…) servSock clntSock servSock clntSock クライアント sock servSock clntSock (データ通信) クライアント sock servSock clntSock サーバ fork() サーバ:close(clntSock) 子:close(servSock) サーバ 子: fork型並行サーバ 反復サーバと並行サーバの対比 反復サーバ(TCPEchoServer.c)は、一度に一つのクラ イアントのみ処理する。 逐次処理。 並行サーバ(TCPEchoServer-Fork.c)は、プロセスや スレッドを利用する並行処理。 プロセスやスレッドにより、1つのクライアントの処理を 独立して動作するサーバのコピーを作成。 サーバのコピーが、複数・並行的に動作する。 fork型並行サーバ 並行サーバのプロセス作成 クライアントの要求毎に、fork() システムコールを使っ て、新しい子プロセスを1つ生成する fork(): 子プロセスを生成 戻り値: 親:子のプロセスID 戻り値: 子:0 子プロセスは終了後、親プロセスがwaitpid()を呼出す までゾンビ状態 fork型並行サーバ 並行サーバのプログラムコードの特徴 平行サーバは、クライアントから接続要求がある度 に自身のコピーを作る。 平行サーバの処理は、自身のコピーを作る以外は、 反復サーバと同じ処理を行う。 平行サーバの親プロセスは、クライアント個別との 通信とサービスを処理する、子プロセスをfork()。 親プロセスは、子プロセスをfork()後、クライアント個 別との通信用のソケット(clntSock)を開放する。 一方、子プロセスは、クライアントからのコネクショ ンを受け付けるためのソケット(servSock)を開放す る。 fork型並行サーバ TCPEchoServer-Fork.c main() #include “TCPEchoServer.h” /* 新しく作ったインクルード */ #include <sys/wait.h> /* waitpid()で利用する */ int main(int argc, char *argv[]) { int servSock; /* サーバのソケット識別子 */ int clntSock; /* クライアントのソケット識別子 */ unsigned short echoServPort; /* サーバのポート番号 */ pid_t processID; /* fork()からのプロセスID */ unsigned int childProcCount = 0; /* 子プロセスの数 */ if (argc != 2) /* 引数の数が正しいかチェック */ { fprintf(stderr, "Usage: %s <Server Port>\n", argv[0]); exit(1); } echoServPort = atoi(argv[1]); /* 第1引数はローカルポート番号 */ servSock = CreateTCPServerSocket(echoServPort); サーバソケットを 作成 fork型並行サーバ TCPEchoServer-Fork.c main() for (;;) /* 永遠に繰返す */ { clntSock = AcceptTCPConnection(servSock); 接続要求毎に /* 子プロセスの作成とエラー報告 */ fork() if ((processID = fork()) < 0) DieWithError("fork() failed"); else if (processID == 0) /* 子プロセスの場合 */ { close(servSock); /* 子は親プロセスのソケットをクローズ */ HandleTCPClient(clntSock); exit(0); /* 子プロセスの終了 */ クライアント処理 } を実行 printf("with child process: %d\n", (int) processID); close(clntSock); /* 親は子のソケットをクローズ */ childProcCount++; /* 未回収の子プロセス数を1増やす */ while (childProcCount) /* 全ゾンビをクリーンアップ */ { processID = waitpid((pid_t) -1, NULL, WNOHANG); if (processID < 0) /* waitpid()のエラーを確認 */ DieWithError("waitpid() failed"); else if (processID == 0) /* ゾンビが存在しない */ break; else childProcCount--; /* 子プロセスを1つ回収 */ } } /* この部分には到達しない */ } ノンブロッキング(ゾンビが いなければ直に戻る) fork型並行サーバ int CreateTCPServerSocket(unsigned short port) fork型並行サーバ int AcceptTCPConnection(int servSock) fork型並行サーバ void HandleTCPClient(int clntSocket) fork型並行サーバ fork型並行サーバPythonプログラム fork_server.py socket+os.forkを使ったpreforkサーバ 概説 ソケットを作った後、MAX_PROC個の子プロセスを生成し、 クライアントからの接続を待ちます。 常にMAX_PROC個の子プロセスが生成されており、 同時に処理できるコネクションも子プロセスの数による。 client.py 1connetion client 概説 サーバに1回接続して、文字列送信後、サーバからの文字列 を受信します。 このクライアントを使用して、サーバのテストを行います。 netutil.py netutil.py コマンドパラメータの取り出しなど。
© Copyright 2025 ExpyDoc