サーバーで複数ポートを待ち受ける
socketは普通にacceptすると処理をblockしてしまうので複数のポートの待ちうけが出来ません。 acceptする前にIO->Selectのcan_readを使用することにより複数ポートの待ちうけが可能になります。
#!/usr/bin/perl use strict; use warnings; use IO::Socket; use IO::Select; my @ports = (6000, 7000); my $select = IO::Select->new; foreach my $port ( @ports ) { my $listen = IO::Socket::INET->new( Listen => SOMAXCONN, LocalPort => $port, Proto => 'tcp', ) or die $@; $select->add($listen); } my @handles; while(@handles = $select->can_read) { foreach my $handle (@handles) { my $new = $handle->accept(); if ( my $pid = fork ) { $new->close(); } else { select($new); print "connect to @{[$new->sockport]}\n"; exit(0); } } }
telnetでアクセスすると6000と7000どちらのポートでもアクセスできることを確認できます。
$telnet localhost 6000 Trying ::1... telnet: connect to address ::1: Connection refused Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. connect to 6000 Connection closed by foreign host.
$ telnet localhost 7000 Trying ::1... telnet: connect to address ::1: Connection refused Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. connect to 7000 Connection closed by foreign host.