Arduino Ether Shieldに早速PINGを撃ち込め!ブラウジングさらせ!、、、 バグ? [ATmarquino Arduino]
chip1 Stopからいらした方、Arduino関連カテゴリをお試しください。http://hamayan.blog.so-net.ne.jp/archive/c2300498101-1
画像はクリックすると拡大できます。
バグ?
ネットワーク物の接続状態や限界を確認するもっとも手軽で、少なくとも同じLAN上でエラーなんぞ発生していたら、ちょっとWAN上での利用は微妙ではない?チェックであるPINGを打ってみた結果がこれです。
まずは普通にPINGを打ってみます。デフォルトのデータサイズは32byteでこれは問題ない様です。そのままデータサイズを増やしていくと119byteまでは問題ない様です。32byteの返信も大体300μs位で返してくるのは流石ハードウエアプロトコルスタックと言えるのかもしれません。
ところが120byteになったとたんミスコンペアを発生しています。おやおや?。
120byte送ったら、確かに120byte返して来ているのですが、キャプチャ画面の様にオフセット119、つまり一番最後のデータがこけている事がパケットモニタでも確認できます。
さて、プロトコルスタックはこのWIZnetのW5100と言うICが実行している筈なので、このICのバグなんでしょうか?。それとも、、、。
W5100のマニュアルを読むと概要のところに16Kbyteのバッファの事が書いてあるので、まさか120byte程度のデータも受信できないなんて事は無いよね。
もう少しマニュアルを読んでみるか。
次に進みます。
Arduino-0015のサンプルのWEBサーバーを実行させてみました。
4枚目の画像です。まあこんな感じでしょうかね。一見!まともに動いているように見えます。
ですが裏ではものすごい事が起きています。
なんとこのサーバー、一文字一文字パケットで送ってきます。言い換えると、一回のパケットにはTCPなら最大1460byte詰め込めますが、実際に送って来るのは1byteだけです。(※しかも1byte毎にPSHしている)
最後の画像はパケットモニターの画面ですが、60byteのパケットが延々と続いているのが判ります。60byteの中身の大半はヘッダーとパディングです。ハイライトしている行の直前の465byteはブラウザからのリクエストです。
普通、この程度のWEB情報なら1回か2回のパケットの送信で完了します。
これはちょっとトホホではないでしょうか。LANなら良いですが、インターネットに接続できません。あまりにもひんしゅくで。
スケッチを見る限りは1byte毎に送るなんて想像も付きませんが、なんでこうなっちゃうんだろう?。
※Serial.printlnから派生しているっぽいから、ブロックデバイスではなくキャラクタデバイス扱いになっちゃうんだろうか?、まあC++詳しく知らないからなんとも言えないけれど。
画像はクリックすると拡大できます。
ネットワーク物の接続状態や限界を確認するもっとも手軽で、少なくとも同じLAN上でエラーなんぞ発生していたら、ちょっとWAN上での利用は微妙ではない?チェックであるPINGを打ってみた結果がこれです。
まずは普通にPINGを打ってみます。デフォルトのデータサイズは32byteでこれは問題ない様です。そのままデータサイズを増やしていくと119byteまでは問題ない様です。32byteの返信も大体300μs位で返してくるのは流石ハードウエアプロトコルスタックと言えるのかもしれません。
ところが120byteになったとたんミスコンペアを発生しています。おやおや?。
120byte送ったら、確かに120byte返して来ているのですが、キャプチャ画面の様にオフセット119、つまり一番最後のデータがこけている事がパケットモニタでも確認できます。
さて、プロトコルスタックはこのWIZnetのW5100と言うICが実行している筈なので、このICのバグなんでしょうか?。それとも、、、。
W5100のマニュアルを読むと概要のところに16Kbyteのバッファの事が書いてあるので、まさか120byte程度のデータも受信できないなんて事は無いよね。
もう少しマニュアルを読んでみるか。
次に進みます。
Arduino-0015のサンプルのWEBサーバーを実行させてみました。
4枚目の画像です。まあこんな感じでしょうかね。一見!まともに動いているように見えます。
ですが裏ではものすごい事が起きています。
なんとこのサーバー、一文字一文字パケットで送ってきます。言い換えると、一回のパケットにはTCPなら最大1460byte詰め込めますが、実際に送って来るのは1byteだけです。(※しかも1byte毎にPSHしている)
最後の画像はパケットモニターの画面ですが、60byteのパケットが延々と続いているのが判ります。60byteの中身の大半はヘッダーとパディングです。ハイライトしている行の直前の465byteはブラウザからのリクエストです。
普通、この程度のWEB情報なら1回か2回のパケットの送信で完了します。
これはちょっとトホホではないでしょうか。LANなら良いですが、インターネットに接続できません。あまりにもひんしゅくで。
スケッチを見る限りは1byte毎に送るなんて想像も付きませんが、なんでこうなっちゃうんだろう?。
client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(); // output the value of each analog input pin for (int i = 0; i < 6; i++) { client.print("analog input "); client.print(i); client.print(" is "); client.print(analogRead(i)); client.println("<br >>"); }
※Serial.printlnから派生しているっぽいから、ブロックデバイスではなくキャラクタデバイス扱いになっちゃうんだろうか?、まあC++詳しく知らないからなんとも言えないけれど。
2009-05-15 01:56
nice!(0)
コメント(8)
トラックバック(3)
177 は、天気予報。
119 は、救急車。
110 も見てみたい。
by noritan (2009-05-15 09:11)
判りました!
では117と104と106も忘れずにやっておきましょう。何が起きるかな?。
by hamayan (2009-05-15 09:23)
Duemilanove に Ether Shield、いいですねぇ。
libraries\Ethernet 辺りをちらっと覗いてみると、utility の socket.c::send や w5100.c::send_data_processing では複数バイト送信に対応しているようですが、上位の client.c や server.c での write が 1 バイトしか扱えないようになっていました。
そこら辺をゴニョゴニョすればあるいは。
by masato (2009-05-15 10:35)
お!、本当だ。
ゴニョゴニョしなくてもsocket.hをインクルードして直接sendを呼び出してしまえばブロックで転送できそうな気がする。
確かにSerial.printlnから派生?させたclient.printlnの方が誰にでも取っ付き易いのかも知れないけれど、インターネットに接続した場合の負荷の増大を考えたら、これを参考に自分で作ってくださいね!的な話はどうかと思うけれど。
絶対にこのサンプルを作った人は、トラフィックの増大に付いて知っているだろうし。
by hamayan (2009-05-15 11:10)
120byte PINGの件は、たぶんW5100のバグです。
自分でドライバを書いていく前にPING試験をやり
ましたが、MACアドレス・IPアドレス・ネットマスク
だけの設定でやったとき、同じように119バイトまで
しか正常じゃないですね。って、いまも同じなんだけど。
意味が分からないので放っておいたのですが、嫌な記憶
が甦ったなぁ(笑)。
by JUN猫 (2009-05-15 21:44)
> 嫌な記憶が甦ったなぁ
(笑)!そうですよね。まだあまり動かしていない段階での検証ですから、ICが悪いのか自分が悪いのか、それともボードが悪いのか、それの切り分けが困難ですからね。
by hamayan (2009-05-15 21:51)
紹介した自分が言うのもアレだけど、WIZnetのサイトで
公開されているドライバのク〇なこと。
どちらにしろ、PINGはハードで行われているのは確実なので
どうしてもエラーなしでやるならIPRAWとかMACRAWモード
でICMPを実装する(って、それじゃハード処理の意味無いぞ)
さらに嫌なのは、過去のドライバにMRレジスタの使われて
ないビットをいじっていたのを見た記憶があって、ここに
解決策がありそうな気がしてならないっていう。
(あくまで気がするだけ)
by JUN猫 (2009-05-15 22:27)
(笑)流石JUN猫さん、色々知っていると言うか、経験済み。
by hamayan (2009-05-15 22:57)