
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
恐れ入ります。
ANo.2で回答した者です。まず最初に、もしかしたら他に方法が有るかも知れない(私自身が無知である)可能性があるとお断りしておきます。(純粋に、自身の経験からのアドバイスになります)
>UDPマルチキャスト受信中にLANケーブルが日常的に抜かれることを想定しているのですが、
基本的にUDPを使うべきではありません。通信にはTCPを使うべきです。
ただし、ブロードキャストやマルチキャストはUDPでしか使えないので、しょうがなくUDPを使います。
その為、日常的にLANケーブルが抜かれる環境下では、マルチキャストもしくはユニキャストでIPを集めてから、TCP(ユニキャスト)で接続し直すべきかと思います。
>ためしに抜き差ししたところ、一回抜くと、再度挿してもUDPを受信しなくなってしまいました。
>(recvfrom()はずっと待ち合わせている状態)
>recvfrom()はずっと待ち合わせているのに、なぜUDPは受信しなくなるのか、その原因を追究しております。
こちらで簡単なサーバクライアントを書いて実験したところ、再接続後に問題なく受信しました。(WindowsのWinsock2を使用)
その為、実装や環境によって違うと思います。
おそらくですが、NICの反応が無くなることでソケットが壊れる(ディスクリプタが使えなくなる)のだと思います。
現象が再現できないため推測になりますが…
お使いのrecvfrom()が一般的であれば、1つ目の引数でディスクリプタを渡すと思います。ソケットが壊れていれば、その時点でエラーが返ってくるはずです。(recvfromで待てない)
エラーが帰ってきた場合は、再度ソケットを作成し直す(recvfromで待てたときはそのまま待つ)という実装で良いかと思います。
ご参考になれば幸いです。
No.2
- 回答日時:
ANo.1で回答した者です。
状況が把握できませんが、何を目的としておいでですか?
非接続型のデータ送受信は「通信異常時」「通信正常時」という状態そのものが存在しません。
つまり、recvfromによる受信待ちは「受信待ち」であって「接続中」ではありません。
# TCP:受信待ち→接続中→受信中→切断
# UDP:受信待ち→受信中→受信待ち
(その為UDPには送信エラーも存在しません。投げっぱなしだからです)
受信待ちの間に、受信側NICが壊れてしまうと言うような事を検出できるかという事でしたら、判りません。(recvfromによる、というよりもsocketに依存しない方法しか思いつきません)
***
tcpdumpは、デバイスレベルで割り込んでいたような…実装依存なのか定義されていたのかちょっと記憶にありません。申し訳ありません。
返信、ありがとうございます。
> 状況が把握できませんが、何を目的としておいでですか?
UDPマルチキャスト受信中にLANケーブルが日常的に抜かれることを想定しているのですが、
ためしに抜き差ししたところ、一回抜くと、再度挿してもUDPを受信しなくなってしまいました。
(recvfrom()はずっと待ち合わせている状態)
recvfrom()はずっと待ち合わせているのに、なぜUDPは受信しなくなるのか、その原因を追究しております。
正常時も長時間UDPがこないことがありうるとして、
LANケーブルを再度挿したら、再度UDPを受信したいのです。
また、通信障害が発生した場合も復旧するまで再接続をリトライしたいため、即時処理終了にはしたくないです。
上記の機能を満たすためにはタイムアウトしたらその都度ソケット再接続してマルチキャストグループにjoinという形になるということですね。
通信状態を検知できれば、タイムアウト時にソケット再接続が必要なのか、そうでないのか判断できると思いまして。
No.1
- 回答日時:
恐れ入ります。
質問の内容を取り違えているかもしれないので、確認させてください。
「UDP通信中にネットワークが切れたことを検知できるか?」というご質問ですか?
上記の質問であると仮定して、以下は回答します。
無理です。
TCPが糸電話だとするならば、UDPは紙飛行機です。
TCPはコネクションを張って通信を行いますが、UDPは投げっぱなしです。
(受信応答などもアプリケーション側で面倒を見てやる必要があります)
一般的には、ネットワークが切れたら困るような信頼性に関わる通信ではUDPは使いません。
***
マルチキャストで通信断を判断するには、タイムアウトを設定しておくのが良いと思います。(タイムアウトしたら通信断だと見なす)
ご参考になれば幸いです。
この回答への補足
下記お礼に加えて、現状の疑問点について補足させてください。
udpもsocketを使用しているため、socket観点で状態確認はできないでしょうか?
poll()を使用してPOLLERR、POLLHUPを監視してみたのですが、異常は検知できませんでした。
また、setsockopt()でIP_RECVERRを付与した場合も、異常は検知できませんでした。
udp通信においては上記は意味をなさないものなのでしょうか?
ご回答、ありがとうございます。
やはり検知できませんか。たとえば、以下の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マルチキャストでは「タイムアウトによるみなし通信切断」だけが通信異常時の制御方法ということですね。
他になにかいいアイデアがあればまたご教授いただければ幸いです。
ひとまず、ご回答ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CSSが全く分かりません、お助け...
-
DLLファイルの逆コンパイラにつ...
-
visual studio 2022でのC#プロ...
-
プログラマー達は何故、プログ...
-
C言語について(初心者)
-
バッチファイルで以下のような...
-
【C言語】全角文字の配列を、全...
-
Windows Formアプリからコンソ...
-
C言語 関数、変数の宣言について
-
プログラミングc++を全く分か...
-
あってる
-
DNCL(共テ用プログラミング言語...
-
逆コンパイルと逆アセンブルの...
-
ArduinoでMouse関数を使用して...
-
Notepad++の関数リスト表示でC...
-
c言語でイベントフラグを使った...
-
C言語の質問です。バイナリ形...
-
int16_t の _t は何?
-
大量のデータを読み込んで表示...
-
C言語の関数のextern宣言
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Outlookの「受信日時」「件名」...
-
TCP/IP のパケットの分断と結合...
-
CRC-CCITTに関しての仕様とサン...
-
Outlookの「受信日時」「送信者...
-
UDP受信時の通信異常検知について
-
ASP.NET C#でPOST受信
-
シリアル通信時のデータ受信方法
-
VC++メッセージの送受信につい...
-
パケット受信 recvfrom( )につ...
-
PC98で232c送信winndowで受信で...
-
「TCPは全二重可能」の意味
-
Windows Mobile6.1 メール受信...
-
ネットワークでの受信バイト数
-
recv関数の戻り値について
-
文字化け
-
TCP/IPで受信エラー
-
Excxel vba でYahoo API で住所...
-
VB2005でTCP/IPソケット通信で...
-
マルチスレッドに挑戦したい
-
TCPのプログラミングで質問…と...
おすすめ情報