68user's page 掲示板

Prev< No. 3328〜3349> 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}を作られていますが、
これはどこで使用されているのでしょうか?
作っとけば勝手にってことなのでしょうか?

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

No. 3342 # 68user 2003/09/16 (火) 02:54:15
>>3341 のぐけん。
> $SIG{PIPE}を作られていますが、これはどこで使用
> されているのでしょうか? 作っとけば勝手にって
> ことなのでしょうか?
勝手に使用されます。

シグナルを最初に受けるのはカーネルです。カーネルは
プロセスごとに「SIGINT がきたらどーする、SIGPIPE が
きたらこーする」というテーブルを参照し、適切な動作を
行います。

つまり %SIG の書き換えというのは、自分のプロセスの
シグナル処理用テーブルを更新なわけで。

No. 3343 # 68user 2003/09/16 (火) 02:55:24
ところで、
    http://x68000.startshop.co.jp/~68user/net/link-book.html#8
の「UNIX ネットワークベストプログラミング入門」ですが、
    UNIX ネットワークプログラミング入門
        http://www.gihyo.co.jp/books/syoseki.php/4-7741-1754-4
として新版が出版されてるのを見付けました。

買ってませんが、立ち読みした限りでは htons は使われて
いました (笑)。大幅な内容追加というわけではないようなので、
「ベスト」の方を持っている人は不要かなーという感じです。

クライアントとサーバ両方を自作してみるというのは重要な
ことだと思いますので、改めてお勧めしておきます。

No. 3344 # Tsun 2003/09/17 (水) 16:50:41
始めまして、Tsunと申します。

何時も勉強させて頂いております。
共通鍵暗号のページで3DESでの鍵長が56*3にならない訳ですが、3DESは
DESプロセスを3回繰り返すと言う意味で、使う鍵は実は2個なのです。
具体的に言うと、56ビットの鍵AとBを用意して、以下の様に暗号化します。

元データ→鍵Aで暗号化→鍵Bで復号化→鍵Aで暗号化→暗号データ
                        (1)    (2)   (3)

(2)で(1)で暗号化したものとは別の鍵で復号化する訳ですから、当然正しく復号されません、しかし見方を変えれば、これは別の鍵で暗号化したものと、同値となります。ただ鍵としては56ビットを2つ使っているだけなので、鍵の強度としては112ビットの鍵長と同等となります。

この方式の利点は、実質的には56ビットの演算量+αで112ビット相当の鍵強度が得られる所にあります。
鍵長と演算量の比は対数的ですから、112ビットの鍵を使って1回演算するより、56ビットの鍵を使って、3回演算するほうが有利となります。

No. 3345 # asachio [E-mail] 2003/09/24 (水) 00:17:10
お世話になります。UNIXを学びはじめて1か月半の初心者です。grep, findの使用方法を完全理解していないためだと思いますが、(すみません。)ある文字列を含む、ファイル名を検索するにはどのように、grepあるいは、findを使用すればよろしいでしょうか?

No. 3346 # 4lj [E-mail] 2003/09/24 (水) 19:02:31
はじめまして。私は普段、

find ./ -type f | xargs grep -n "foo"

とかやってますが。後はお好みでgrepに-iつけてみたり。

No. 3347 # pranky [E-mail] 2003/09/25 (木) 01:06:50
こんばんは初めまして。pranky と申します。
ここで、いつもネットワークプログラミングなどを勉強させて頂いております。

今回 TCP で実装してあった双方向のプロトコルをファイアウォールにも
対応させなくてはならなくなり、困っているのでご相談させて下さい。
今のところ考えているのは、現在の TCP のプロトコルを HTTP の上に乗せて
HTTP プロキシに対応する事でファイアウォールを越えようと考えています。

開発言語は Perl を使用しておりますので、テスト的に HTTP:Daemon モジュールを
使用してサーバを構築し、LWP::UserAgent でクライアントとして動作を
させてみました。

1. 基本的に既存のプロトコルが Peer to Peer なので、起動時にクライアント側から
サーバ側へ HTTP 接続をし、その起動中はつないだままにしておきたい。

2. 接続中はクライアント側からもサーバ側からも数KB 位のデータのやりとりを
双方向で行いたい。

この上記2 点は両立するものでしょうか?
上の 1. は keepalive を行えばできそうな感じはしますが、下の 2. はできる
のでしょうか。

通常のブラウザを見ていると
1. サーバ側へファイル要求
2. サーバ側がファイル送信
という事の繰り返しですが、MSN Messenger が HTTP を使用している事を
考えると上記の 1. 2. の両立が出来そうな気がします。

No. 3348 # YK 2003/09/25 (木) 10:25:24
はじめまして。
いつもUNIXの情報を参考にさせて頂いております

現在、あるファイルに書かれたファイル名を取得し
そのファイル名が存在するか判定するCシェルを作成しております

set FILE_NAME = `awk '{printf $1}' fileA`

というコマンドでファイル名は取得できたのですが、
ファイル内で改行されている際に改行コードまで取得してしまい
ファイルの存在判定が正しく行えません

改行を除外してファイル名を取得する事は出来ないでしょうか?

ご存知でしたら御教授して頂きたく思います
宜しくお願い致します

赤色の文字は 「Windows 機種依存文字」か、いわゆる「半角カナ」です。 この掲示板では自動変換されますが、今後は使用しないで下さい

No. 3349 # 68user 2003/09/25 (木) 15:40:16
>>3344 Tsun
勉強になります。ありがとうございます。

もうちょっと勉強して自分のモノにしてから web の方も
修正したいと思います。

>>3345 asachio
> ある文字列を含む、ファイル名を検索するには
「ある文字列を含むファイル」の名前の一覧がほしいなら
>>3346 4lj
で紹介していただいた方法で。

じゃなくて「ファイル名にある文字列を含むファイル」の名前の
一覧が欲しいのなら
      % find /dir -name \*hoge\* -print
などなど。

>>3347 pranky
> 1. 基本的に既存のプロトコルが Peer to Peer なので、起動時に
> クライアント側からサーバ側へ HTTP 接続をし、その起動中は
> つないだままにしておきたい。
> 2. 接続中はクライアント側からもサーバ側からも数KB 位のデータの
> やりとりを双方向で行いたい。
1 は keep alive を使ったとしても、proxy のタイムアウトが
ある or あるかもしれないので無理ではないかと思います。

2 も HTTP ではサーバプッシュができないので、純粋な意味での
双方向通信は無理ではないでしょうか (サーバから不定期に
クライアントにデータを送るのは不可能だが、クライアントが
定期的にサーバに接続し、そのレスポンスにサーバからのデータを
載せるなら可能)。

> MSN Messenger が HTTP を使用している事を考えると上記の
> 1. 2. の両立が出来そうな気がします。
MSN Messenger は UPnP を使用しており、UPnP が HTTP の上を
流れているだけです。よって、純粋な HTTP では実現不可能では
ないかと思います。

どこまで実現可能かは、プロトコルの詳細がわからないとなんとも
言えないです。

>>3348 YK
> set FILE_NAME = `awk '{printf $1}' fileA`
> ファイル内で改行されている際に改行コードまで取得してしまい、
> ファイルの存在判定が正しく行えません。
csh は set foo=`bar` とした時点で改行コードを除去すると思う
のですが、改行コードまで取得してしまうというのは本当でしょうか?
どういう方法で改行コードが原因だと確認されましたか?

UNIX の改行コードは 0x0a ですが、DOS や Windows は 0x0d 0x0a
です。それが残っているのであれば、tr などで 0x0d を削除してください。
      http://x68000.startshop.co.jp/~68user/unix/pickup?tr

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