技術メモ

神奈川在住のITエンジニアの備忘録。おもにプログラミングやネットワーク技術について、学んだことを自分の中で整理するためにゆるゆると書いています。ちゃんと検証できていない部分もあるのでご参考程度となりますが、誰かのお役に立てれば幸いです。

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 は分けて管理されているはずなので試すまでもなかったが、一応やってみた。