モジュールを使ってみよう (3)

前へ << モジュールを使ってみよう (2) HTTP の並行アクセス >> 次へ

IO::Select

これまで IO::Socket モジュールを使った いくつかの例を出しましたが、 最も効果的なのは IO::Select モジュールと組み合わせたときです。

IO::Select モジュールも標準モジュールなので、インストールする 必要はありません。

echo-server-select-io-socket.pl

    1: #!/usr/local/bin/perl
    2: 
    3: # $Id: echo-server-select-io-socket.pl,v 1.1 2001/04/21 18:56:41 68user Exp $
    4: 
    5: use IO::Socket;                   # IO::Socket モジュールを使う。
    6: use IO::Select;
    7: 
    8: $port = shift || 5000;            # ポート番号を設定
    9: 
   10: $listening_socket = IO::Socket::INET->new(LocalPort => $port,
   11:                                           Listen    => SOMAXCONN,
   12:                                           Proto     => 'tcp',
   13:                                           Reuse     => 1,
   14:                                          );
   15: 
   16: if ( ! $listening_socket ){
   17:     die "listen できませんでした。 $!\n";
   18: }
   19: 
   20: $selecter = IO::Select->new;
   21: $selecter->add($listening_socket);
   22: 
   23: while (1){
   24:     ($active_socks) = IO::Select->select($selecter,undef,undef,undef);
   25:     
   26:     foreach $sock (@{$active_socks}){
   27:         if ( $sock == $listening_socket ){
   28:             print "NEW CLIENT\n";
   29:             $new_sock = $listening_socket->accept;
   30:             $selecter->add($new_sock);
   31:         } else {
   32:             print "NEW MESSSAGE\n";
   33:             $buf = <$sock>;
   34:             if ( $buf ){
   35:                 print $sock $buf;
   36:                 $sock->flush();
   37:             } else {
   38:                 $selecter->remove($sock);
   39:                 $sock->close();
   40:             }
   41:         }
   42:     }
   43: }
select データに対してビット操作を行う必要がないので、非常に 短く書くことができます。
   20: $selecter = IO::Select->new;
で、select データの生成、
   21: $selecter->add($listening_socket);
   30:             $selecter->add($new_sock);
で、追加。
   38:                 $selecter->remove($sock);
で、削除です。4引数 select を使うのと比べると、非常にお手軽ですね。

ただし、IO::Select が使えるのは、IO::Socket で生成した ソケットについてのみです。つまり

  • socket 関数と select 関数
  • IO::Socket モジュールと IO::Select モジュール
の組み合わせは OK ですが、
  • socket 関数と IO::Select
は NG です。
前へ << モジュールを使ってみよう (2) HTTP の並行アクセス >> 次へ

ご意見・ご指摘は Twitter: @68user までお願いします。