- ベストアンサー
ネットワーク通信でのudpパケットの通信における付加情報とは?
- ネットワーク通信で困っていることがあります。2装置間でudpパケットの通信を行っている際に、過去に送ったudpパケットとなることがあります。その際、パケットにトレイラーとFCSなるものが付加されていることがわかりました。
- 質問1として、これらの付加情報を取得することは可能なのでしょうか?もし可能であれば、エラー処理が可能です。
- 質問2として、これらの付加情報が付く原因は何が考えられるでしょうか?
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
まずFCSだが、これは原則として「全ての」パケットについている筈だ。 (TCP/IP等のIPパケット以外でもという意味だ) 【参考:FCS】 http://ja.wikipedia.org/wiki/Frame_Check_Sequence で、通常のパケットダンプには出てこない。 何故なら、出てくる必要がないから。 もしも出てくる必要があるとしたら、そのフレーム自体がFCSチェックの結果エラーと判定されたパケットの場合だけだと思う。 FCSエラーが出たパケットは「破棄される」と書かれているので、おそらくドライバレベルで捨てられている可能性が高い。 質問主殿が書かれている情報から、何が起きているのか私なりに推測すると ・伝送中にパケットが損傷し、FCSエラーとなりLANドライバレベルでパケットが破棄された ・アプリ側はパケットが破棄されたにも拘らず、もう一度読み込みバッファを読みに行ったのでバッファにあったひとつ前に来たパケットのデータをもう一度読み込んだ 辺りではないだろうか。 質問1及び質問2の回答と被るのだが、質問主殿はTCPプロトコルとUDPプロトコルの違い(長所・短所)はご存知だろうか? 文章を読む限り、そのアプリはUDPプロトコルでデータを送っていいような種類のモノではないような気がするのだが。 UDPはデータが途中でロストしてもアプリの実行に影響のないケースに使うようなプロトコルです。 UDPは伝送結果の確認を行なっていないのです。 TCPは伝送結果の確認をちゃんと行なっていますので、途中でパケットが1つロスト(破棄)された場合は、ちゃんと再送処理をプロトコル側でしてくれます。 TCPが重過ぎるためにUDPを使っているなら、今回のようにパケット破棄されてデータがロストした場合に備え必要最小限のチェック処理やエラー回復処理をアプリ側が責任を持って行なう必要があります。 (送信パケット内のデータ部にシーケンス番号を割り振って、番号が途中で飛んでいないかチェックし、飛んでいた場合は再送要求するとか)
その他の回答 (1)
- kusa_mochi
- ベストアンサー率76% (1597/2087)
私はこのような伝送を扱うアプリを作った事がないので、その辺りの事情は良く分かりませぬ。 その辺は御自身で関数の仕様を調べるか、他の回答者から回答が付くのを待ってみて下さい。 #回答が付かないようなら、この質問は締めて別の質問としてそれ専用のカテゴリに改めて質問を投稿される事をお勧めします
お礼
御丁寧にありがとうございます。 とりあえずは調査は継続します。何か進展ありましたアップしますので、宜しくお願いします。 調査と並行にですが、パケットが重複しても問題なく動作するための対策も考案中です。 今考えているのは、過去に受信したパケットを一定期間保持しておき、パケット受信毎に過去のパケットかどうかをチェックするように考えています。 他に何か良い案があれば教えてください。 以上、宜しくお願いします。
補足
いつもお世話になっております。 調査した結果色々分かりましたので、これまでの内容も含めて以下にまとめます。 FCSエラーが発生する原因については某CPUメーカの技術資料の注意事項で記載されていました(その内容についてはここでは割愛します)。 また、前回の補足で「FCSエラーのパケットを破棄した」と記述しましたが実際は破棄していないことが分かりました。 そこでFCSエラー発生時はドライバ内部で破棄するはずなのになぜ破棄しないのか調査したところ、skb->ip_summed変数に「CHECKSUM_NONE」を入れないとFCSエラーパケットを破棄しないようなことがウェブで記載されていました。 ただ、この変数をどのようにして使うのか不明です。 この辺ことを知っている方がいれば教えてください。 宜しくお願いします。
お礼
早速のお返事ありがとうございました。非常に参考となりました。 >・伝送中にパケットが損傷し、FCSエラーとなりLANドライバレベルでパケットが破棄された >・アプリ側はパケットが破棄されたにも拘らず、もう一度読み込みバッファを読みに行ったのでバッファにあったひとつ前に来たパケットのデータをもう一度読み込んだ 恐らく後者の現象が発生していると思います。 つまり、recv関数で受信待ちさせた状態で、ドライバがFCSがおかしいと判断してそのパケットを破棄した場合は、recv関数が受信したと誤動作するということでしょうか?また、そのようなことも想定したプログラムにしないといけないということでしょうか? 以上、たびたびの質問ですがよろしくお願いします。