3

これはWindows7のC++にあります...私は一種の初心者のマルチキャストソケットの人であり、このコードを他の誰かから継承しました。

このシステムでは、複数のコンピューターがADDR 225.1.1.2でマルチキャストソケットを作成/参加し(なぜそうではないのか)、ソケットが接続されると、定期的に相互に「チャット」してさまざまなメッセージを送信します。ネットワーク上で1台のコンピューター(「A」と呼びます)を起動し、1秒に1回定期的に「キープアライブ」メッセージを送信させても、何も受信されていない(マルチキャストアドレスに接続している他のユーザーがいない)場合は、そのままにしておきます。約3分間、次に別のコンピューターBを起動すると、最初のコンピューターAはコンピューターBからのブロードキャストメッセージを認識しません。Bはパケットの送信でエラーを取得しておらず、Aは何も受信してエラーを発生していません(受信が呼び出されることはありません)。何かが受信部分をシャットダウンしている場合に通知を受け取る方法、またはそのような情報を登録する方法がわかりません。

2台のマシンを比較的近くで起動すると、各マシンは他のマシンのキープアライブパケットを認識します。受信は両方のマシンで発生します。しかし、繰り返しになりますが、最初のコンピューターを起動してから3分を超えて、2番目のコンピューターを起動すると、最初のコンピューターのReceiveメソッドがスリープ状態になったか、なくなったか、昏睡状態になっているようです。エラーは生成されませんが、プレーンにはマシンBのパケットは表示されません。(さらに、デバッガーの出力に3つのスレッドが存在しますが、それらは私が作成したスレッドではなく、システムスレッドです)。ただし、最近起動したマシンBは、マシンAからのキープアライブパケットを確認します。

ソケット呼び出しは次のとおりです。

hSock = WSASocket(
    AF_INET,
    SOCK_DGRAM,
    0,
    NULL,
    0,
    WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF | WSA_FLAG_OVERLAPPED);

setsockopt(hSock,SOL_SOCKET,SO_REUSEADDR,(char *) &bVal,sizeof(bVal));
srcIP.sin_family=AF_INET;

// Need to bind to local interface
srcIP.sin_addr.s_addr=inet_addr(("225.1.1.2"); // htonl(INADDR_ANY);
srcIP.sin_port=htons(5555);
bind( hSock,(struct sockaddr FAR *) &srcIP,sizeof(srcIP) );

nIP_TTL=36;
setsockopt(hSock,IPPROTO_IP,IP_MULTICAST_TTL,(char *) &nIP_TTL,sizeof(int));

mreq.imr_multiaddr.s_addr=inet_addr("225.1.1.2");
mreq.imr_interface.s_addr=inet_addr("225.1.1.2");
setsockopt(hSock,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *) &mreq,sizeof(mreq));

これが私がインターネットで出くわしたものです:

  1. 受信バッファがいっぱいになっている可能性があります。(マルチキャストを使用しているネットワーク上にあるのはコンピューターAだけなので、そうは思いません)
  2. ファイアウォールは、数分後に受信オンマルチキャストをオフにするように設定できます。(私はこれを信じていません)
  3. WinSockプロトコルは、X分間非アクティブになった後、マルチキャストの受信をオフにする可能性があります。(私もこれを信じていません)
4

1 に答える 1

1

上記のコードに誤りがあると思います。imr_interface には、コンピューターのネットワーク インターフェイスのローカル IP アドレスを指定する必要があると思います (通常は、マルチキャスト アドレスではなく、コンピューターの IP アドレスです)。つまり、マルチキャスト トラフィックを送受信するインターフェイスです。あなたのコードはマルチキャスト グループに参加したことがなく、しばらくの間偶然に機能しただけだと思います。

IP_ADD_MEMBERSHIP の呼び出しにまったく失敗した場合でも、数分間は機能する場合があります。

奇妙な 3 分間の動作は、動作していない参加または IGMP スヌーピングの問題のように聞こえます。

IPv4 マルチキャストは非常に微妙であり、ホスト、オペレーティング システム、および中間のハードウェア コンポーネントの動作も非常に微妙です。

オペレーティング システムは、アプリケーションがマルチキャストを処理するときに IGMP メッセージを送受信します。これは自動的に行われ、IP_ADD_MEMBERSHIP などへの正しい呼び出しに依存しますが、これを制御することはできません。中間のハードウェア コンポーネント (WLAN ルーター、スイッチ、電力線アダプターなど) はすべて魔法のようにマルチキャストを機能させますが、この魔法は問題を隠したり、問題を引き起こしたりする傾向があります。

1 つの例: プロセスがマルチキャスト アドレス X に対して IP_ADD_MEMBERHIP を呼び出した場合、IP_ADD_MEMBERSHIP の呼び出しに失敗した場合でも、マシン上の他のすべてのプロセスもアドレス X からのマルチキャスト トラフィックを認識します。

欠落した (または偽の) ADD_MEMBERSHIP の典型的な症状は次のとおりです。ケーブルが引っ張られたかのように、数分間 (通常は 3 ~ 5 分) 動作し、その後突然動作を停止します。プログラムの 1 つを再起動すると、次の 3 ~ 5 分間、問題が再び修正されます。しかし、100% 正しい ADD_MEMBERSHIP を使用しても、Powerline-Adapter のような重要なネットワーク コンポーネントを通過するときに、このような症状が発生する可能性があります。次に、これは、使用している OS と、使用しているルーター/スイッチ/アダプターとの間のある種の非互換性です。

これをデバッグするには、ホスト OS の IGMP 状態を調べてみてください。ただし、Windowsでこれを行う方法がわかりません。

于 2015-10-21T22:34:32.100 に答える