IPv6 はdual stackで書くのが普通。つまり、getaddrinfo で、接続可能なすべてのアド レスを取ってきて、それを全部待つ。そして、どれかに接続できるまで全部試す。
perldoc perlipc は、あまり update されてなくて、dual stack な書き方は皆無。あら らら。
Socket ではなくて、OOな IO::Socketを使えと。なるほど。でも、全然動きません。
IO::Socket->new(PeerAddress=>$addr);とかすると、generic socket は作れないとか文句を言う。そこで、
IO::Socket::INET IO::Socket::INET6ってのがあるのがわかって、それは、もちろん、IPv4 only / IPv6 only 。これで dual stack を書くのは無理だ。
で、 IO::Socket::IP ってのを作った人がいるらしいというのはわかりましたが、
* defalut では入ってないから、cpan で入れろ
そうなのか。そこで、メゲそうになったんですが、
my ($err,@res) = getaddrinfo($host0, $port0, {socktype=>SOCK_STREAM}); for my $res (@res) { my ($err1, $host, $port) = getnameinfo($res->{addr},NI_NUMERICHOST | NI_NUMERICSERV); print STDERR "Trying to connect to $host : $port...\n";とすれば良いということがわかりました。OOな皮だけ作って、中のsocketを自分で law evel で作ってやれば良いわけね。おそらく、Perl5のdual stack なsocketの作り方は 、これが一番ましでしょう。
my $sock = new IO::Socket; $sock->socket($res->{family}, $res->{socktype}, $res->{protocol}) || next; if ($sock->connect($res->{addr})) { print STDERR "connected to $host port $port\n"; return $sock; } $sock->close; }
http://www.ie.u-ryukyu.ac.jp/~kono/os/ex/etc/client-io.pl http://www.ie.u-ryukyu.ac.jp/~kono/os/ex/etc/server-io.plです。
Cでやるとさらに面倒くさい。Java は楽。Ruby/Python は Perl とおんなじようなもの らしいです。
No comments:
Post a Comment