ないものは自作してみるということで。

Vista は telnet コマンドが無効化されている
ところが Cygwin から telnet コマンドが使えなくて焦った。 Cygwin の setup を確認したり PATH を確認したり。 コマンドプロンプトからも駄目。

ざっとこんなところか。

ptelnet.pl
#!/usr/local/bin/perl
use strict;
use warnings;
use IO::Socket::INET;

my $addr = shift || die "$0 host [port]";
my $serv = shift || 'telnet';
my $port = do {
    no warnings 'numeric';
    $serv + 0
      || getservbyname( $serv, 'tcp' )
      || die "Unknown Service: $serv";
};

my $socket = IO::Socket::INET->new(
    PeerAddr => $addr,
    PeerPort => $port
) or die "$addr:$port $!";

defined(my $pid = fork()) or die "fork failed: $!";
if ($pid) {
    # parent keeps reading from the remote host
    STDOUT->autoflush(1);
    STDOUT->print($_) while <$socket>;
    kill INT => $pid;
}
else {
    # child keeps writing to the remote host
    $socket->autoflush(1); # unnecessary if IO::Socket::INET->VERSION >= 1.18
    $socket->print($_) while <STDIN>;
    exit;
}

使い方は、telnet command と全くおなじ。ただし、接続と切断はいちいち警告しない。簡潔なおかげで、むしろtelnet commandには出来ないこんなことも出来る。

# echo 'GET / HTTP/1.0' | perl ptelnet.pl www.dan.co.jp http > http.out

あと、CRLFとかも厳密には処理していないが、このあたりは読者の宿題ということで。

ちょっと心配なのがwindowsにおけるforkの実装。入出力を分けて処理するためにfork()するというのは、Unixでは常套手段なのだけど、Windowsにはfork()がないのでWindowsではperlはthreadをつかってエミュレートしている。レポートきぼんぬ。

なお、このあたりはCookbookのCh. 16に詳しい。このCh. 16だけでも買う価値があると思う。Perlで比較的低レベルのネットワークプログラミングを解説しているのは他にあまりないので。

Dan the Just Another Perl Networking Hacker