[Tokyo.pm] ll P3-3 (Re: 7月例会)

Keiichi Okabe okabek @ beige.ocn.ne.jp
2003年 7月 21日 (月) 11:37:48 CDT


岡部です。

>> llのメーリングリストですでに流れていますが,明日の22時までに
>> スタッフにまで連絡する必要がありますので.

>20時です(書いた本人)。^^;

ありゃ,失礼しました.早川さぁ〜ん,小山さぁ〜ん.

>いざとなったらなひが4.036で書きます!(袋叩きにされそう

それはそれとして,面白いかも.

んでもって,P3-3用スクリプトができました.以下のようになります.
まだバグってるかもしれませんが,とりあえず流しますので,
叩いておくんなまし.使ったのは,ActivePerl Build804
v5.8.0 MSWin32-x86-multi-thread 版です.
テスト用に使った「じゃんけんサーバ」のスクリプトは別メールで
流します.

-----------------------------------------------------
#!perl
# jyanken.pl
#  for ll-saturday at 030809
#   by keiichi @ tokyo.pm.org
#
use IO::Socket;
use IO::Select;
use strict;

sub notice();

my $remote         = 'localhost';
#my $remote        = 'rrr.rin.gr.jp';
my $remote_port    = 2003;
my $local_udp_port = 2003;
my $local_tcp_port = 2004;
my @hand           = ("PAPER\r\n","SCISSORS\r\n","ROCK\r\n");
my $sel_r          = new IO::Select;
my $sel_w          = new IO::Select;
my ($poll,$notify,$status);

## ポーリングを受けるための設定
#
$poll = IO::Socket::INET->new(
  Proto     => 'tcp',
  LocalPort => $local_tcp_port,
  Listen    => SOMAXCONN,
  Reuse     => 1
) or die "can't setup tcp server";
$sel_r->add($poll);

## 勝ち負けを知るための設定
#
$status = IO::Socket::INET->new(
  Proto     => 'udp',
  LocalPort => $local_udp_port,
  Reuse     => 1
) or die "can't setup udp server";
$sel_r->add($status);

## 使っているポート番号を通知するための設定
#
notice();

while(my @ready = IO::Select::select($sel_r,$sel_w,undef)){
  ## じゃんけんサーバからのアクセス
  #
  if($ready[0]){
    for my $fh (@{$ready[0]}){
      ## じゃんけんサーバからTCPでアクセス
      #
      if($fh == $poll){
        my $new = $poll->accept;
        $sel_r->add($new);
      ## じゃんけんサーバからUDPでアクセス
      #
      }elsif($fh == $status){
        $_ = <$fh>;
        if (/100/){
          notice();
          print "決定\n";
        }elsif(/110/){
          print "まだまだ";
        }elsif(/120/){
          print "負けた\n";
        }elsif(/130/){
          print "あいこ\n";
        }
      ## じゃんけんサーバが'CALL'発行
      #
      }else{
        $_ = <$fh>;
        if (/CALL/){
          my $hand = $hand[int(rand(2))];
          print $fh $hand;
          print $hand;
        }
        $sel_r->remove($fh);
        $fh->close;
      }
    }
  }
  ## じゃんけんサーバへのアクセス
  #
  if ($ready[1]){
    for my $fh (@{$ready[1]}){
      ## IPアドレスとポート番号を通知
      #
      if($fh == $notify){
        my $message = 
          $notify->sockhost . ':' . $local_tcp_port . "\r\n";
        print $notify $message;
        $sel_w->remove($fh);
        $fh->close;
      ## 想定外
      #
      }else{
        die "ouch!";
      }
    }
  }
}

## 使っているポート番号を通知するための設定
#
sub notice()
{
  $notify = IO::Socket::INET->new(
    Proto    => 'tcp',
    PeerAddr =>  $remote,
    PeerPort =>  $remote_port
  ) or die "can't connect to port $remote_port on $remote: $!";
  $sel_w->add($notify);
}
-----------------------------------------------------
-- 
okabek @ beige.ocn.ne.jp  岡部 恵一
成功出於衆者、先知也、先知者、必取於人、知敵之情者也
          孫子 用間篇 第十三



Tokyo-pm メーリングリストの案内