perlによるネットワークプログラミングに関するメモ

ネットワークプログラミングでは、主にソケット処理のプログラムを記述していきます。
ソケットとは、ネットワークに関連したファイルディスクリプタで、下記のように作成されます。

use Socket;

my $sock;
socket( $sock, PF_INET, SOCK_STREAM, getprotobyname('tcp') );


このようにして作成された$sockを通して、通信を行ないます。
色々な関数に$sockを渡すようになります。


ソケットでのネットワークプログラムは、大まかに下記のような流れになっています。

  1. ソケットを作成 (sockt())
  2. 接続先の情報を作成 (sockaddr_in())
  3. ソケットを介して接続 (connect())
  4. ソケットを介したデータの書き込み (print $sock)
  5. 受信 (select(), poll(), epoll())
  6. データ読み込み
  7. ソケットを閉じる (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多重化の他に、マルチプロセス、マルチスレッドといった手法が取られます。
どのタイミングで子プロセス/子スレッドを作成するかは、色々な戦略があるようです。