Akira's Blog

神奈川在住のITエンジニアの雑記です。主にプログラミング(Perl, Java など)やネットワーク技術についての小ネタを、ちょっとずつ書いていきます。

tcp/udpポートを確保し続けるスクリプト

tcp/udpポートを確保し続ける perl スクリプト holdPort.pl を作成した。テスト等でポート・バッティングを起こすために、指定したポートを確保したい時に使うと便利。
使い方は簡単で、例えば「perl holdPort.pl -p 80」で、このスクリプトは停止するまで 80/tcp を握り続ける。udpポートを握りたい場合は、「perl holdPort.pl -p 80 -u」とする。

holdPort.pl

use strict;
use warnings;
use Socket;
use Getopt::Long 'GetOptions';

my $port;
my $udp;
GetOptions(
    'port=i' => \$port,
    'udp'    => \$udp
);

my $packAddr = sockaddr_in($port, INADDR_ANY);
my $serverSock;

if ($udp) {
    #------------------
    # UDP
    #------------------
    socket($serverSock, PF_INET, SOCK_DGRAM, getprotobyname('udp'))
        or die "Cannot create socket: $!";
    bind($serverSock, $packAddr) or die "Cannot bind $port: $!";
    
    while (1) {
        recv($serverSock, my $buf, 1024, 0) or die "Cannot recv: $!";
    }
}
else {
    #------------------
    # TCP
    #------------------
    socket($serverSock, PF_INET, SOCK_STREAM, getprotobyname('tcp'))
        or die "Cannot create socket: $!";
    bind($serverSock, $packAddr) or die "Cannot bind $port: $!";
    listen($serverSock, SOMAXCONN) or die "Cannot listen: $!";

    my $clientSock;
    while (1) {
        accept($clientSock, $serverSock) or die "Cannot accept: $!";
    }
}

ちなみに、このスクリプトが 80/tcp を握っている状態で、別プロンプトから実行した同スクリプトに 80/udp を握らせたら、問題なく握れた。つまり、同じポート番号でも tcpudp では別物となるということ。
# これまで tcpudp とで同じポート番号を使ってポート・バッティングしたとか聞いたことないし、そもそもOS内で tcpudp は分けて管理されているはずなので試すまでもなかったが、一応やってみた。