|
>>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 の部分を削っています。 # 説明文で使用していない用語 (カウンタ) を、ソースで使ってはいけませんね。 |
|
先日質問させていただいた、tomtomです。 クライアントが受信待ちの状態の時に、サーバに ソケットをクローズされたら、クライアントは、 どうなるのでしょうか? 以前質問させていただいた時に、undefを受信してしまう という問題があったのですが、サーバ側で勝手にセッションを 終了してしまっていた可能性があるので、その辺が関係している かどうか疑問に思ったため、再度質問させていただきました。 |
|
あ〜っ、なるほど! わかりました!完璧にわかって疑問が紐解けましたよ〜! get_domainの再起呼び出し後はそういう処理だったんですね…。 カウンタの意味もわかりましたし(^^;)、もうばっちりです! 長々と本当にありがとうございましたm(_ _)m もしまた何かありましたら…よろしくお願いいたします(^^; |
|
こんにちは、今Perl で UDP 通信を行うスクリプトを作っているの ですが、少し分からないところがあるので質問させてください。 普通に UDP 通信は問題なく行えているのですが、送信元の IP アドレスが 拾えなくて悩んでおります。 recv 関数の戻り値で「送信元のアドレス」は拾えるのですが、送信元が 「どこへ宛てて送信したか?」が分からないのです。 IO::Socket::INET モジュールを使用していますが、peeraddr メソッドを 使っても何も返ってきません。 http://x68000.startshop.co.jp/~68user/net/udp-3.html に UDP で connect 出来ると書かれていますが、connect すれば送信先アドレスを 拾う事ができますでしょうか? ご存じの方、よろしくお願いいたします。 |
|
>>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) が使えるということです。 |
|
68user さん、お返事ありがとうございます。 socket => connect を行う事で send を呼ぶ時に IP アドレスを 指定しなくても良くなるわけですね。 逆に recv などで受信する時はどうなのでしょうか。 例えば 192.168.0.255 宛のブロードキャストメッセージを受信しても 受信側からはブロードキャストメッセージを受信したのか、ユニキャストを 受信したのか分かりません。 Java などで UDP を使う時は相手が送信した IP アドレスと相手の IP アドレス両方が分かるようですが、Perl では難しいのでしょうか? |
|
ちょっと前にこのページが移転するかもと言っていましたが、 継続して使わせていただけることになりました。 68user's page は Startshop さん http://www.startshop.co.jp/ 両毛インターネットさん http://www.takauji.or.jp/ Netboy さん のご厚意により、回線・マシンを無料で使用させていただいて おります。ここに改めて感謝の意を表したいと思います。 |
|
>>3333 lopper > 例えば 192.168.0.255 宛のブロードキャストメッセージを受信しても > 受信側からはブロードキャストメッセージを受信したのか、ユニキャストを > 受信したのか分かりません。 一般的な BSD ソケットの API を使う以上は判断できないと思っています。 > Java などで UDP を使う時は相手が送信した IP アドレスと相手の IP > アドレス両方が分かるようですが、Perl では難しいのでしょうか? Java なら受け取ったデータグラムがブロードキャスト宛かどうかを 判断できるのでしょうか。 もしそうなら、Java が BSD ソケット API を使用せずネットワーク 機能を自前で作っているとは考えづらいので、BSD ソケット API で 実現可能なのだろうと思います。 DatagramSocket や DatagramPacket を見る限りでは、Java であっても 無理ではないかと思いましたが、もし可能なのであれば Java で記述 したサンプルプログラムを見せていただけますでしょうか。 |
|
おお、それはすばらしいですね。 もし私が両毛地方とか県南・県央(一部重複してますが)に住むことに なったら、率先して両毛インターネットさんを選びたいという気持ち でいっぱいです。 |
|
お返事ありがとうございます。 確実に Java で宛て先アドレスを取得できるという確認はしていない のですが、以下の IP Messenger for Java の中では行っている ようです。 http://www1.ttv.ne.jp/~digitune/Java/IPMsg/ からソースコードをダウンロードして、その中にある IPMProxyEvent.java ファイルの中にある、getToIPMAddress で見ている見たいです。 P.S. 私は Java には詳しくはないので、確実かどうかわかりません。 |
|
>>3336 へにか > 率先して両毛インターネットさんを選びたいという気持ちでいっぱいです。 本当に一銭たりともお金を払っていないので申し訳ないことです。 機会があればぜひとも。 >>3337 lopper > IPMProxyEvent.java ファイルの中にある、getToIPMAddress で > 見ている見たいです。 ぱっと見、Java 版 IP Messenger 独自機能である proxy 機能の ソースのように見えます。README には「proxy 機能は TCP で実装 されている」とありましたので、多分違うのではないかと思います。 ちなみに 本家 IP Messenger は、受けたメッセージがブロード キャストだと、ログに「(多)」などと表示されます。 しかしこれは UDP のレイヤで判別しているのではなくて、IP Messenger のアプリで使用するコマンドの IPMSG_BROADCASTOPT が 立っているかどうかで判断しています。 |
|
lopper です。 お返事ありがとうございます。 ブロードキャストの件了解しました。なるほど Java版 ではプロキシに TCP を 使用しているので IP アドレスが拾えるのですね。わかりました。 色々とありがとうございました。自分なりに他の道を探してみます。 |
|
tomtomです。 68userさん、お返事ありがとうございます。 そうですか、、もし、undefを返すなら以前の 説明がつくと思ったのですが、どうやら見当違い のようですね。 また、色々考えてみる事にします。 原因が分かったら、また書き込みさせていただきます。 |
|
こんにちわ。以前質問させてもらった者です。 それで、また質問なのですが(笑 Perlカテゴリの中のProxy Serverのことで質問です。 SIGPIPEシグナルが飛んで来た時用 ということで、$SIG{PIPE}を作られていますが、 これはどこで使用されているのでしょうか? 作っとけば勝手にってことなのでしょうか? お忙しいかと思いますが、よろしくお願いします。 |
|
>>3341 のぐけん。 > $SIG{PIPE}を作られていますが、これはどこで使用 > されているのでしょうか? 作っとけば勝手にって > ことなのでしょうか? 勝手に使用されます。 シグナルを最初に受けるのはカーネルです。カーネルは プロセスごとに「SIGINT がきたらどーする、SIGPIPE が きたらこーする」というテーブルを参照し、適切な動作を 行います。 つまり %SIG の書き換えというのは、自分のプロセスの シグナル処理用テーブルを更新なわけで。 |
|
ところで、 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 は使われて いました (笑)。大幅な内容追加というわけではないようなので、 「ベスト」の方を持っている人は不要かなーという感じです。 クライアントとサーバ両方を自作してみるというのは重要な ことだと思いますので、改めてお勧めしておきます。 |
|
始めまして、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回演算するほうが有利となります。 |
|
お世話になります。UNIXを学びはじめて1か月半の初心者です。grep, findの使用方法を完全理解していないためだと思いますが、(すみません。)ある文字列を含む、ファイル名を検索するにはどのように、grepあるいは、findを使用すればよろしいでしょうか? |
|
はじめまして。私は普段、 find ./ -type f | xargs grep -n "foo" とかやってますが。後はお好みでgrepに-iつけてみたり。 |
|
こんばんは初めまして。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. の両立が出来そうな気がします。 |
|
はじめまして。 いつもUNIXの情報を参考にさせて頂いております。 現在、あるファイルに書かれたファイル名を取得し、 そのファイル名が存在するか判定するCシェルを作成しております。 set FILE_NAME = `awk '{printf $1}' fileA` というコマンドでファイル名は取得できたのですが、 ファイル内で改行されている際に改行コードまで取得してしまい、 ファイルの存在判定が正しく行えません。 改行を除外してファイル名を取得する事は出来ないでしょうか? ご存知でしたら御教授して頂きたく思います。 宜しくお願い致します。 |
|
>>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 |