• 締切済み

UDP受信時の通信異常検知について

お世話になります。 UDPマルチキャストを勉強しているのですが、 recvfrom()で受信を待っている間にifdownなどでネットワーク断が 発生した場合、一般的にどうやってそれを検知するのでしょう? tcpdumpではifdownを打つと同時にNetwork is down.と表示された ので、なんらかの方法で検知できるとは思うのですが、、、 どなたかご存じでしたらご教授ください。

みんなの回答

  • fonera
  • ベストアンサー率52% (38/72)
回答No.3

恐れ入ります。ANo.2で回答した者です。 まず最初に、もしかしたら他に方法が有るかも知れない(私自身が無知である)可能性があるとお断りしておきます。(純粋に、自身の経験からのアドバイスになります) >UDPマルチキャスト受信中にLANケーブルが日常的に抜かれることを想定しているのですが、 基本的にUDPを使うべきではありません。通信にはTCPを使うべきです。 ただし、ブロードキャストやマルチキャストはUDPでしか使えないので、しょうがなくUDPを使います。 その為、日常的にLANケーブルが抜かれる環境下では、マルチキャストもしくはユニキャストでIPを集めてから、TCP(ユニキャスト)で接続し直すべきかと思います。 >ためしに抜き差ししたところ、一回抜くと、再度挿してもUDPを受信しなくなってしまいました。 >(recvfrom()はずっと待ち合わせている状態) >recvfrom()はずっと待ち合わせているのに、なぜUDPは受信しなくなるのか、その原因を追究しております。 こちらで簡単なサーバクライアントを書いて実験したところ、再接続後に問題なく受信しました。(WindowsのWinsock2を使用) その為、実装や環境によって違うと思います。 おそらくですが、NICの反応が無くなることでソケットが壊れる(ディスクリプタが使えなくなる)のだと思います。 現象が再現できないため推測になりますが… お使いのrecvfrom()が一般的であれば、1つ目の引数でディスクリプタを渡すと思います。ソケットが壊れていれば、その時点でエラーが返ってくるはずです。(recvfromで待てない) エラーが帰ってきた場合は、再度ソケットを作成し直す(recvfromで待てたときはそのまま待つ)という実装で良いかと思います。 ご参考になれば幸いです。

  • fonera
  • ベストアンサー率52% (38/72)
回答No.2

ANo.1で回答した者です。 状況が把握できませんが、何を目的としておいでですか? 非接続型のデータ送受信は「通信異常時」「通信正常時」という状態そのものが存在しません。 つまり、recvfromによる受信待ちは「受信待ち」であって「接続中」ではありません。 # TCP:受信待ち→接続中→受信中→切断 # UDP:受信待ち→受信中→受信待ち (その為UDPには送信エラーも存在しません。投げっぱなしだからです) 受信待ちの間に、受信側NICが壊れてしまうと言うような事を検出できるかという事でしたら、判りません。(recvfromによる、というよりもsocketに依存しない方法しか思いつきません) *** tcpdumpは、デバイスレベルで割り込んでいたような…実装依存なのか定義されていたのかちょっと記憶にありません。申し訳ありません。

puri_tarou
質問者

お礼

返信、ありがとうございます。 > 状況が把握できませんが、何を目的としておいでですか? UDPマルチキャスト受信中にLANケーブルが日常的に抜かれることを想定しているのですが、 ためしに抜き差ししたところ、一回抜くと、再度挿してもUDPを受信しなくなってしまいました。 (recvfrom()はずっと待ち合わせている状態) recvfrom()はずっと待ち合わせているのに、なぜUDPは受信しなくなるのか、その原因を追究しております。 正常時も長時間UDPがこないことがありうるとして、 LANケーブルを再度挿したら、再度UDPを受信したいのです。 また、通信障害が発生した場合も復旧するまで再接続をリトライしたいため、即時処理終了にはしたくないです。 上記の機能を満たすためにはタイムアウトしたらその都度ソケット再接続してマルチキャストグループにjoinという形になるということですね。 通信状態を検知できれば、タイムアウト時にソケット再接続が必要なのか、そうでないのか判断できると思いまして。

  • fonera
  • ベストアンサー率52% (38/72)
回答No.1

恐れ入ります。 質問の内容を取り違えているかもしれないので、確認させてください。 「UDP通信中にネットワークが切れたことを検知できるか?」というご質問ですか? 上記の質問であると仮定して、以下は回答します。 無理です。 TCPが糸電話だとするならば、UDPは紙飛行機です。 TCPはコネクションを張って通信を行いますが、UDPは投げっぱなしです。 (受信応答などもアプリケーション側で面倒を見てやる必要があります) 一般的には、ネットワークが切れたら困るような信頼性に関わる通信ではUDPは使いません。 *** マルチキャストで通信断を判断するには、タイムアウトを設定しておくのが良いと思います。(タイムアウトしたら通信断だと見なす) ご参考になれば幸いです。

puri_tarou
質問者

お礼

ご回答、ありがとうございます。 やはり検知できませんか。たとえば、以下のtcpdumpコマンドを実行したのちに、 ifdownを打った場合、以下の用に出力されました。 1. tcpdump -i eth0 udp #tcpdump実行(udpを指定) 2. ifdown eth0 #eth0をdown 3. tcpdumpの出力(以下) tcpdump: pcap_loop: recvfrom: Network is down 3 packets captured 8 packets received by filter 0 packets dropped by kernel 上記メッセージを見ると、pcap_loop()からrecvfrom()をコールしているように見えました。 そこで、udp受信にてrecvfrom()を使った場合に「Network is down」が検知できるのでは?と考えた次第です。 tcpdumpの場合は、udp接続とは別の仕組みで別にネットワーク監視を行っているのでしょうか。 recvfrom()によるudpマルチキャストでは「タイムアウトによるみなし通信切断」だけが通信異常時の制御方法ということですね。 他になにかいいアイデアがあればまたご教授いただければ幸いです。 ひとまず、ご回答ありがとうございました。

puri_tarou
質問者

補足

下記お礼に加えて、現状の疑問点について補足させてください。 udpもsocketを使用しているため、socket観点で状態確認はできないでしょうか? poll()を使用してPOLLERR、POLLHUPを監視してみたのですが、異常は検知できませんでした。 また、setsockopt()でIP_RECVERRを付与した場合も、異常は検知できませんでした。 udp通信においては上記は意味をなさないものなのでしょうか?

関連するQ&A