ネットワークプログラミングでは、主にソケット処理のプログラムを記述していきます。
ソケットとは、ネットワークに関連したファイルディスクリプタで、下記のように作成されます。
use Socket; my $sock; socket( $sock, PF_INET, SOCK_STREAM, getprotobyname('tcp') );
このようにして作成された$sockを通して、通信を行ないます。
色々な関数に$sockを渡すようになります。
ソケットでのネットワークプログラムは、大まかに下記のような流れになっています。
- ソケットを作成 (sockt())
- 接続先の情報を作成 (sockaddr_in())
- ソケットを介して接続 (connect())
- ソケットを介したデータの書き込み (print $sock)
- 受信 (select(), poll(), epoll())
- データ読み込み
- ソケットを閉じる (close())
受信する場合、プログラムはブロッキング(blocking)されます。
ブロッキングが行なわれている間は、プログラムは停止します。
ですので、I/Oを多重化したい、という考えがでてきます。
I/Oを多重化するために、複数のソケットを扱う方法があります。
複数のソケットを扱うために、OSによりkqueue()かepoll()という関数を使用します。
この点でのOSの違いを吸収するために「libev」「libevent」というCライブラリがあります。
perlでは、「Event::Lib」と「Danga::Socket」というモジュールがあります。
「Event::Lib」は、libeventのラッパーです。
「Danga::Socket」は、IO::KQueue(kqueue(2))とIO::Poll(poll(2))を透過的に扱えるライブラリです。
I/O多重化の他に、マルチプロセス、マルチスレッドといった手法が取られます。
どのタイミングで子プロセス/子スレッドを作成するかは、色々な戦略があるようです。