指定されたIP+ポートについて、ネットワークからのマルチキャストメッセージを読み取るための次のコードがあります
private static void ReceiveMessages(int port, string ip, CancellationToken token)
{
Task.Factory.StartNew(() =>
{
using (var mUdpClientReceiver = new UdpClient())
{
var mReceivingEndPoint = new IPEndPoint(IPAddress.Any, port);
mUdpClientReceiver.ExclusiveAddressUse = false;
mUdpClientReceiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
mUdpClientReceiver.ExclusiveAddressUse = false;
mUdpClientReceiver.Client.Bind(mReceivingEndPoint);
mUdpClientReceiver.JoinMulticastGroup(IPAddress.Parse(ip), 255);
while (!token.IsCancellationRequested)
{
byte[] receive = mUdpClientReceiver.Receive(ref mReceivingEndPoint);
Console.WriteLine("Message received from {0} ",mReceivingEndPoint);
}
}
});
}
このマルチキャストip+portでデータを取得する2つのネットワークアダプターがあります(各ネットワークアダプターを監視するwiresharkの2つのインスタンスによって確認されます)。Wiresharkでは、両方のネットワークカードでこれらのポート+ IP)に大量のトラフィックが発生しています。
問題は、コンソールに1つのネットワークカードからのメッセージしか表示されないことです。
netstatで再確認しましたが、ポートでリッスンしている他のソフトウェアはありません。
では、なぜ2枚のネットワークカードのうち1枚だけからトラフィックを取得しているのでしょうか。
編集:
私も次のことを試しました:
private static void ReceiveMessages(int port, string ip, CancellationToken token, IEnumerable<IPAddress> ipAddresses)
{
foreach (IPAddress ipAddress in ipAddresses)
{
IPAddress ipToUse = ipAddress;
Task.Factory.StartNew(() =>
{
using (var mUdpClientReceiver = new UdpClient())
{
var mReceivingEndPoint = new IPEndPoint(ipToUse, port);
mUdpClientReceiver.ExclusiveAddressUse = false;
mUdpClientReceiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
mUdpClientReceiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
mUdpClientReceiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, 1);
mUdpClientReceiver.ExclusiveAddressUse = false;
mUdpClientReceiver.Client.Bind(mReceivingEndPoint);
mUdpClientReceiver.JoinMulticastGroup(IPAddress.Parse(ip), 255);
Console.WriteLine("Starting to listen on "+ipToUse);
while (!token.IsCancellationRequested)
{
byte[] receive = mUdpClientReceiver.Receive(ref mReceivingEndPoint);
Console.WriteLine("Message received from {0} on {1}", mReceivingEndPoint,ipToUse);
}
}
});
}
}
「CorrectIPでのリッスンの開始」が2回表示されますが(2つのIPの場合)、1つのネットワークカードからのデータのみが表示されます。
編集2
私も奇妙なことに気づきました。すべてのデータを受信するインターフェイスを無効にしてからソフトウェアを起動すると、他のインターフェイスからデータを取得できるようになります。インターフェイスを再度アクティブにしてソフトウェアを再起動しても、非アクティブ化されていないカードでトラフィックが発生します。
そして、私は自分に応答するデバイスがあり、1つのネットワーク(両方ではない)にのみ接続されていることを確かに知っています
編集3
もう1つのこと:私(localhost)からメッセージを送信すると、私が持っているすべてのネットワークカードで、2つのネットワークインターフェイスにメッセージが届くのがわかります。しかし、プログラムを2回起動すると、最初のプログラムだけがメッセージを受け取り、2番目のプログラムはメッセージを受け取りません。
編集4
最初のコメントに続く追加情報:2つのイーサネットカードがあります。1つは10.10.24.78
IPを使用し、もう1つはIPを使用し10.9.10.234
ます。データを送信するのは私ではなく、ネットワーク部分です(5353
このIPを持つポートは、mDNSに使用される既知のマルチキャストアドレスであるため、プリンター、iTunes、Mac、および作成したその他のソフトウェアからトラフィックを受信する必要があります)。データはIP
224.0.0.251
とポートでマルチキャストされます5353
。
これは、いくつかのIPでデータを送信するために使用できるコードですが、前述のように、ローカルで開始すると、ほとんど機能します(ただし、1つのローカルクライアントのみがメッセージを受信します)。
private static void SendManuallyOnAllCards(int port, string multicastAddress, IEnumerable<IPAddress> ipAddresses)
{
foreach (IPAddress remoteAddress in ipAddresses)
{
IPAddress ipToUse = remoteAddress;
using (var mSendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
{
mSendSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,
new MulticastOption(IPAddress.Parse(multicastAddress)));
mSendSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 255);
mSendSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
var ipep = new IPEndPoint(ipToUse, port);
//IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(multicastAddress), port);
mSendSocket.Bind(ipep);
mSendSocket.Connect(ipep);
byte[] bytes = Encoding.ASCII.GetBytes("This is my welcome message");
mSendSocket.Send(bytes, bytes.Length, SocketFlags.None);
}
}
}
編集5
これが私のroute print
(そのコマンドを知らなかった)結果です、そして私の2つのIPで、私は常にデータを受け取ります10.9.10.234
編集6
私は他のいくつかのことを試しました:
- UdpClientの代わりに受信するソケットを使用してください->機能しませんでした
- リーダーに追加のsocketOptionを設定します(DontRoute = 1、Broadcast = 1)->機能しませんでした
- リーダーSocketが使用する必要のあるMulticastInterfaceを指定します(socketOption MulticastInterfaceを使用)->機能しませんでした