68user's page 掲示板

Prev< No. 3328〜3341> Next  [最新発言に戻る] [過去ログ一覧]
No. 3328 # 68user 2003/09/09 (火) 21:36:40
>>3327 ken
> そのあと再びget_domainサブルーチンを呼び出すところからが…
> どうなるのでしょうか??(^^;
http://x68000.startshop.co.jp/~68user/net/resolver-2.html#6 の例だと、
最初に get_domain が受け取った $data が
      (0x04)www2(0xC0)(0x13)....
で、一回目の while ループが終了した時点で
        $data = "(0xC0)(0x13)...."
        @domains=('www2');★1
となっています。

二回目の while ループでは
      my $len = unpack('C', $data);
で $len は 0xC0 になり、
      if ( ( $len & 0xc0 ) == 0xc0 ){
が真なので
      my $offset = unpack('n', $data) ^ 0xc000;
          ⇒ $offset は 0x13
      my $new_data = substr($org_data, $offset);
          ⇒ $new_data は、UDP データグラム全体 ($org_data) の 0x13バイト目
      substr($data, 0, 2) = '';
          ⇒ $data は "(0xC0)(0x13)...." から "...." となる (先頭 2バイトを削る)
となります。$new_data には
      (0x09)startshop(0x02)co(0x02)jp(0x00)
が入っています。

ここで
     my ($domain_part) = get_domain($new_data, $org_data);★2
        push(@domains, $domain_part);★3
と get_domain を再帰呼び出しすると、
      sub get_domain {
            my ($data, $org_data) = @_;
の $data には
      (0x09)startshop(0x02)co(0x02)jp(0x00)....
が入っています。再帰呼び出しされた get_domain が処理を終えるときには
        @domains = ('startshop', 'co', 'jp');
となっており、最終的に
        return 'startshop.co.jp';
とドメインの一部を返します。

で、再帰呼び出しした側の get_domain に処理が戻ると、以下のような
流れになります。
    ★1 の @domains にはすでに www2 が入っている
    ★2 の $domain_part には、再帰呼び出しした get_domain から受け取った startshop.co.jp が入っている
    ★3 で @domains = ('www2', 'startshop.co.jp') となる


> また、else文の中の1行はどういった意味を持っているのでしょうか?
> ここでいう「カウンタ」という物もよくわからなくて…。
      (0x03)www(0x02)jp(0x07)FreeBSD(0x03)org(0x00)
の 3・2・7・3・0 がここでいうカウンタです。$len には
その後に続くバイト長が入っており、
      508: substr($data, 0, 1) = '';
はその $len の部分を削っています。

# 説明文で使用していない用語 (カウンタ) を、ソースで使ってはいけませんね。

No. 3329 # tomtom 2003/09/10 (水) 10:17:13
先日質問させていただいた、tomtomです。
クライアントが受信待ちの状態の時に、サーバに
ソケットをクローズされたら、クライアントは、
どうなるのでしょうか?

以前質問させていただいた時に、undefを受信してしまう
という問題があったのですが、サーバ側で勝手にセッションを
終了してしまっていた可能性があるので、その辺が関係している
かどうか疑問に思ったため、再度質問させていただきました。

No. 3330 # ken 2003/09/10 (水) 23:11:50
あ〜っ、なるほど!
わかりました!完璧にわかって疑問が紐解けましたよ〜!
get_domainの再起呼び出し後はそういう処理だったんですね…。
カウンタの意味もわかりましたし(^^;)、もうばっちりです!
長々と本当にありがとうございましたm(_ _)m
もしまた何かありましたら…よろしくお願いいたします(^^;

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
おお、それはすばらしいですね。
もし私が両毛地方とか県南・県央(一部重複してますが)に住むことに
なったら、率先して両毛インターネットさんを選びたいという気持ち
でいっぱいです。

No. 3337 # lopper [E-mail] 2003/09/14 (日) 00:31:47
お返事ありがとうございます。
確実に Java で宛て先アドレスを取得できるという確認はしていない
のですが、以下の IP Messenger for Java の中では行っている
ようです。

http://www1.ttv.ne.jp/~digitune/Java/IPMsg/
からソースコードをダウンロードして、その中にある IPMProxyEvent.java
ファイルの中にある、getToIPMAddress で見ている見たいです。

P.S.
私は Java には詳しくはないので、確実かどうかわかりません。

No. 3338 # 68user 2003/09/14 (日) 01:12:32
>>3336 へにか
> 率先して両毛インターネットさんを選びたいという気持ちでいっぱいです。
本当に一銭たりともお金を払っていないので申し訳ないことです。
機会があればぜひとも。

>>3337 lopper
> IPMProxyEvent.java ファイルの中にある、getToIPMAddress で
> 見ている見たいです。
ぱっと見、Java 版 IP Messenger 独自機能である proxy 機能の
ソースのように見えます。README には「proxy 機能は TCP で実装
されている」とありましたので、多分違うのではないかと思います。

ちなみに 本家 IP Messenger は、受けたメッセージがブロード
キャストだと、ログに「(多)」などと表示されます。

しかしこれは UDP のレイヤで判別しているのではなくて、IP
Messenger のアプリで使用するコマンドの IPMSG_BROADCASTOPT が
立っているかどうかで判断しています。

No. 3339 # lopper [E-mail] 2003/09/14 (日) 03:13:58
lopper です。
お返事ありがとうございます。
ブロードキャストの件了解しました。なるほど Java版 ではプロキシに TCP を
使用しているので IP アドレスが拾えるのですね。わかりました。

色々とありがとうございました。自分なりに他の道を探してみます。

No. 3340 # tomtom 2003/09/15 (月) 09:10:42
tomtomです。
68userさん、お返事ありがとうございます。
そうですか、、もし、undefを返すなら以前の
説明がつくと思ったのですが、どうやら見当違い
のようですね。
また、色々考えてみる事にします。
原因が分かったら、また書き込みさせていただきます。

No. 3341 # のぐけん。 2003/09/15 (月) 12:15:50
こんにちわ。以前質問させてもらった者です。

それで、また質問なのですが(笑
Perlカテゴリの中のProxy Serverのことで質問です。
SIGPIPEシグナルが飛んで来た時用
ということで、$SIG{PIPE}を作られていますが、
これはどこで使用されているのでしょうか?
作っとけば勝手にってことなのでしょうか?

お忙しいかと思いますが、よろしくお願いします。

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