|
こんにちは、今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 |
|
Solaris8で (1) 100M Full-Duplex (2) 1000M Full-Duplex が混在(共存)している環境を設定するには、どうしたらいいでしょうか。 因みに (1) hme0 (2) ge0, ge1 という名で認識されるようです。 よろしくお願いします。 |
|
>>3347 pranky ファイアウォールがHTTP/1.1のCONNECTメソッドの使用を許可している環境で あればそれを使用すれば解決しますね。 CONNECTの使用ができない場合にはHTTPトンネルと呼ばれるソフトウェアを使用すれば 良いと思います。 私が以前作成したHTTPトンネルが http://www.jumperz.net/index.php?i=2&a=0&b=0 にあります。 68userさんのおっしゃる >2 も HTTP ではサーバプッシュができないので、純粋な意味での > 双方向通信は無理ではないでしょうか (サーバから不定期に > クライアントにデータを送るのは不可能だが、クライアントが > 定期的にサーバに接続し、そのレスポンスにサーバからのデータを > 載せるなら可能)。 を実装したものとなっています。 その他上記URLからリンクしていますが、C言語で書かれたGNU Httptunnelなど同じ種類の ソフトウェアがいくつか存在します。 |
|
名づけのページを作っています。 漢字の組み合わせで名前を作るため 例えば 亜xあyあい 井xい のようなデーターを作り while(<FILE>){ chomp; $key=$_; ($key,$values)= split(/x/, $_); $t3{$key}=$values; } のような連想配列に入れていました。 (色々と考えて漢字のデータはeuc,cgiスクリプトはsjisです) これを使って名づけのCGIをホームページで公開しているのですがある人から「治」という字が使えないとメールがありなぜかなと考えてみました。 ローカル(windowsXP)な環境ではキチンと表示されます。がプロバイダにアップロードすると使えなくなります。(wakwakとNETAGEどちらも) そこでアップロードして実験してみました。 @rkey= values %t3; @rkey2= keys %t3; これでキチンと配列が作られているか---連想配列は出来ていました。 次に $nnn='治'; &jcode'convert(*nnn,"euc"); $us=$t3{$nnn}; とやってみたのですがこれだと$usの値が見つかりませんでした。 そこで コードのせいかと思い単純に $nnn='治';#これはsjis &jcode'convert(*nnn,"euc"); として$nnnをHTML(euc)で表示したらコードの変換がうまくいかないようで文字化けします。 そこで $nnn='治'; &jcode'convert(*nnn,"euc"); $code=&jcode'getcode(*nnn); としてコードのチェックをしてみたのですが何もコードの判別ができないのです。 ちなみに違う漢字では上の実験はキチンと反応しました。 結果どうも治の文字コードの変換がうまくいかないように思うのですがどうしたらいいのかわからないのです。何かいい方法はありませんか?教えてください。お願いします。 |
|
>>3351 金床 金床さま、はじめまして pranky です。 ありがとうございます! http tunnel で調べてみたところ CPAN に http-tunnel を実装した モジュールがありましたので、簡単なソフトを作成して AnHTTPD と 一緒に使用してみたところ、TCP が接続できました! この方法で試してみます! |
|
>>3350 セルゲイ > (1) 100M Full-Duplex > (2) 1000M Full-Duplex > が混在(共存)している環境を設定するには、どうしたらいいでしょうか。 100M な NIC と 1000M な NIC の 2枚差しではダメでしょうか。 って、まわりにギガビットな環境が全くないのでわからない んですけどね。 >>3352 落合 Shift_JIS の「治」は 0x8e 0xa1 ですが、EUC-JP の半角カナの 句点「。」も 0x8e 0xa1 だからです。 > $nnn='治'; > &jcode'convert(*nnn,"euc"); > $code=&jcode'getcode(*nnn); > としてコードのチェックをしてみたのですが何もコードの > 判別ができないのです。 jcode.pl を読めばわかりますが、理論的にエンコーディングの 正確な自動判断は不可能なので、 - EUC-JP として解釈できるバイト数 - Shift_JIS として解釈できるバイト数 を比べ、バイト数が大きい方を getcode の結果としています。 しかし 0x8e 0xa1 の場合はどちらも 2バイトなので判断がつかず getcode は undef を返します。 > 色々と考えて漢字のデータはeuc,cgiスクリプトはsjisです であれば、jcode.pl にエンコーディングを教えてやればよいです。 &jcode'convert(*nnn, 'euc', 'sjis'); # perl4 的な書き方 jcode::convert(\nnn, 'euc', 'sjis'); # perl5 的な書き方 と書けば、きっちりと Shift_JIS から EUC-JP に変換してくれます。 |
|
>>3344 Tsun > 共通鍵暗号のページで3DESでの鍵長が56*3にならない訳ですが せっかく教えていただいたので、勉強してみました。といっても 暗号技術大全 http://www.amazon.co.jp/exec/obidos/ASIN/4797319119/ref%3Db%5Fbb%5F1%5F25/249-2894126-9073950 を読んだだけですが。 「鍵Aで暗号化 → 鍵Bで復号化 → 鍵Aで暗号化」という方法を EDE (Encrypt-Decrypt-Encrypt) と言う。DES なら DES-EDE などと書く。 Encrypt-Decrypt-Encrypt が特に解読しづらいわけではないので、 Encrypt-Encrypt-Encrypt でも別に構わない。 ただ、EDE の利点は、鍵A と 鍵B を同じにすれば一度だけ暗号化 したのと同じ結果が得られること (DES-EDE に対応しておけば、 DES にも対応したことになる)。 なぜ 3回必要なのか、2回の暗号化 (つまり 2DES) ではダメな 理由はというと、2回の暗号化では中間値探索 (meet-in-the-middle) 攻撃に弱いため。56bit の DES で 2回暗号化した場合、総当たり 攻撃に限ると 112bit の強さを持つが、中間値探索には 57bit の 強さしかない。 3DES には鍵を 2つ使う方法と、3つ使う方法がある。 鍵を 3つ使う 3DES は総当たりに対しては 56*3=168bit の強度が あるが、中間値探索に対しては 112bit の相当の強度になる。 一方、鍵を 2つ使う 3DES は中間値探索の弱点はないため、総当たりと 中間値探索のいずれに対しても 112bit の強度になる。 よって、現実的な強さとしては鍵 3つの方が優秀である。 OpenSSL で実装されている暗号で言うと、 鍵2つの 3DES: des-ede-cbc(=des-ede), des-ede-cfb, des-ede-ofb 鍵3つの 3DES: des-ede3-cbc(=des-ede3=des3), des-ede3-cfb, des-ede3-ofb となる。 ただ、 > 鍵長と演算量の比は対数的ですから、112ビットの鍵を使って > 1回演算するより、56ビットの鍵を使って、3回演算するほうが > 有利となります。 ここはよくわかりませんでした。DES の鍵は結局は 16ラウンド それぞれの 48bit 内部鍵の元となるだけなので、対数的ではない のではないかと思いました。 |
|
ども。おひさしぶりです。 これまでときどき私のlinux環境からDNSの名前解決ができない という件でいろいろと相談させて戴いていましたが、今回たまたま Redhat 9 publisher editionをインストールし試してみたところ、 なぜか無事名前解決できるようになりました。 もしかしたらこれまでインストール時に何かのチェックボックスに チェックを入れなかったなど、気づいていなかったミスがあったかも しれませんが、とにかく使えるようになりましたのでまずはご報告 します(もうしないかもしれませんが…^^;)。 というわけでこれまでいろいろアドバイスいただきまして、どうも ありがとうございました。これで晴れて開発環境を手に入れ、無事 プログラミングにいそしむことができます。今後もどうぞよろしく お願いします。 |
|
「ネットワークプログラミングの基礎知識」の「リンク集・参考書籍」 http://x68000.startshop.co.jp/~68user/net/link-book.html を更新し、以下の書籍の紹介を追加しました。 - C言語による TCP/IP ネットワークプログラミング - IPv6 ネットワークプログラミング - 暗号技術大全 - 暗号解読―ロゼッタストーンから量子暗号まで― 一番お勧めなのは、「暗号解読」のところで触れている フェルマーの最終定理 http://shinchosha.co.jp/cgi-bin/webfind3.cfm?ISBN=539301-4 だったりします。 # 次点が「暗号解読」 |
|
はじめましてyudaiと申します。 突然お邪魔して誠に失礼とは思いますが、ご教授いただけませんでしょうか? Perlでファイルオープン open(TESDAT, "tesdata.txt" ); #エラー処理略 @list=<TESDAT>; #testdata.txt内容 m_A9<>太郎<>26歳 f_C5<>花子<>23歳 m_G7<>一郎<>19歳 #ここまで 等として読み込むと 1行ごとに配列の要素となると思うのですが、、この場合に添え字[2]でなく要素の値(f_C5等)で参照する方法はございませんか? htmlフォームから"f_C5"の入力を受け取りtesdata.txtを読み込み文字列を参照して $ID="f_C5"; $name="花子"; $old="23歳"; のような結果を得たいのです。 尚、データベースモジュールは使えない環境です。 乱文にて恐縮ではございますがどうかお教えください。 |
|
>>3356 has > なぜか無事名前解決できるようになりました。 そうですか、原因がわからず解決してしまって残念です :-) ときにウチの環境でも返ってくる AAAA レコードが壊れていたり、 DNS サーバからの返事がなかなか返ってこなかったり、と思ったら 急になおったり、使用する DNS サーバを変えると再現しなかったり、 でも動作がおかしい DNS サーバはひとつではなかったり、と なかなか大変です。 >>3358 yudai 案1: my $input_id = 'f_C5'; # web からの入力 open(TESDAT, "tesdata.txt" ); while (<TESDAT>){ chomp; my ($ID, $name, $old) = split($_, '<>'); if ( $ID eq $input_id ){ # なんらかの処理 } } 案2: my $input_id = 'f_C5'; # web からの入力 my %namehash; my %oldhash; open(TESDAT, "tesdata.txt" ); while (<TESDAT>){ chomp; my ($ID, $name, $old) = split($_, '<>'); $namehash{$ID} = $name; $oldhash{$ID} = $old; } if ( defined $namehash{$input_id} ){ # なんらかの処理。 # print "$input_id $namehash{$input_id} $oldhash{$input_id}\n"; # とか。 } というのが回答になっていますか? |