68user's page 掲示板

Prev< No. 3331〜3336> Next  [最新発言に戻る] [過去ログ一覧]
No. 3331 # lopper [E-mail] 2003/09/12 (金) 18:51:13
こんにちは、今Perl で UDP 通信を行うスクリプトを作っているの
ですが、少し分からないところがあるので質問させてください。

普通に UDP 通信は問題なく行えているのですが、送信元の IP アドレスが
拾えなくて悩んでおります。
recv 関数の戻り値で「送信元のアドレス」は拾えるのですが、送信元が
「どこへ宛てて送信したか?」が分からないのです。
IO::Socket::INET モジュールを使用していますが、peeraddr メソッドを
使っても何も返ってきません。

http://x68000.startshop.co.jp/~68user/net/udp-3.html に UDP で
connect 出来ると書かれていますが、connect すれば送信先アドレスを
拾う事ができますでしょうか?

ご存じの方、よろしくお願いいたします。

No. 3332 # 68user 2003/09/13 (土) 01:35:39
>>3329 tomtom
> クライアントが受信待ちの状態の時に、サーバにソケットを
> クローズされたら、クライアントは、どうなるのでしょうか?
単に相手がソケットをクローズしただけなら、recv は 0 を
返します。

もし
      A が listen → B が connect → A がソケットクローズ
      → B が send → B が recv
なら、B は SIGPIPE を受けます。


>>3331 lopper
> recv 関数の戻り値で「送信元のアドレス」は拾える
> のですが、送信元が「どこへ宛てて送信したか?」が
> 分からないのです。
ソケットが送信先を記憶していないからです。同じ相手に
連続して UDP データグラムを送信する場合、
    socket(SOCKET, PF_INET, SOCK_DGRAM, 0);
    send(SOCKET, "hoge1", 0, $sock_addr);
    send(SOCKET, "hoge2", 0, $sock_addr);
と、毎回 send の引数に宛先である $sock_addr を指定
しなければいけません。なぜなら、一度目の send を
実行した後、SOCKET は $sock_addr に送信したことを
覚えていないからです。

# ソケットの先のアドレスが確定していないので、相手側で
# エラーがあって ICMP メッセージが返ってきても、カーネルは
# どのソケットにエラーを伝えればよいかわからない。だから
# 非 connect な UDP では相手側のエラーを拾えないわけです。

> connect すれば送信先アドレスを拾う事ができますでしょうか?
できます。
    socket(SOCKET, PF_INET, SOCK_DGRAM, 0);
    connect(SOCKET, $sock_addr);
この処理で SOCKET は「宛先が $sock_addr であること」を
覚えます。よって、この後 send する場合は
    send(SOCKET, "hoge1", 0);
と宛先を省略できるのです。

C で言うと、connect(2) することで、sendto(2) ではなく
send(2) が使えるということです。

No. 3333 # lopper [E-mail] 2003/09/13 (土) 22:21:38
68user さん、お返事ありがとうございます。
socket => connect を行う事で send を呼ぶ時に IP アドレスを
指定しなくても良くなるわけですね。

逆に recv などで受信する時はどうなのでしょうか。
例えば 192.168.0.255 宛のブロードキャストメッセージを受信しても
受信側からはブロードキャストメッセージを受信したのか、ユニキャストを
受信したのか分かりません。
Java などで UDP を使う時は相手が送信した IP アドレスと相手の IP
アドレス両方が分かるようですが、Perl では難しいのでしょうか?

No. 3334 # 68user 2003/09/13 (土) 22:25:12
ちょっと前にこのページが移転するかもと言っていましたが、
継続して使わせていただけることになりました。

68user's page は
      Startshop さん http://www.startshop.co.jp/
      両毛インターネットさん http://www.takauji.or.jp/
      Netboy さん
のご厚意により、回線・マシンを無料で使用させていただいて
おります。ここに改めて感謝の意を表したいと思います。

No. 3335 # 68user 2003/09/13 (土) 23:01:58
>>3333 lopper
> 例えば 192.168.0.255 宛のブロードキャストメッセージを受信しても
> 受信側からはブロードキャストメッセージを受信したのか、ユニキャストを
> 受信したのか分かりません。
一般的な BSD ソケットの API を使う以上は判断できないと思っています。

> Java などで UDP を使う時は相手が送信した IP アドレスと相手の IP
> アドレス両方が分かるようですが、Perl では難しいのでしょうか?
Java なら受け取ったデータグラムがブロードキャスト宛かどうかを
判断できるのでしょうか。

もしそうなら、Java が BSD ソケット API を使用せずネットワーク
機能を自前で作っているとは考えづらいので、BSD ソケット API で
実現可能なのだろうと思います。

DatagramSocket や DatagramPacket を見る限りでは、Java であっても
無理ではないかと思いましたが、もし可能なのであれば Java で記述
したサンプルプログラムを見せていただけますでしょうか。

No. 3336 # へにか 2003/09/13 (土) 23:07:33
おお、それはすばらしいですね。
もし私が両毛地方とか県南・県央(一部重複してますが)に住むことに
なったら、率先して両毛インターネットさんを選びたいという気持ち
でいっぱいです。

Prev< No. 3331〜3336> Next  [最新発言に戻る] [過去ログ一覧]