2013-03-07 10 views
5

I次のコードは、指定したIP +ポートUDP:すべてのネットワーク・インタフェースからデータを読む

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); 
       } 
      } 
     }); 
} 

私は2つのネットワークアダプタをしましたしましたから、ためにネットワークからマルチキャストメッセージを、読むことをしましたこのマルチキャストIP +ポート上のデータは、各ネットワークアダプタを監視するwiresharkの2つのインスタンスによって確認されます。私は両方のネットワークカードのためにwiresharkでこれらのポート+ Ipに来る多くのトラフィックを見る)。

問題は私のコンソール上で、私は唯一のネットワークカードからのメッセージを参照してくださいということです。私はnetstatコマンドで確認倍増

は、私は私のポートで待機して他のソフトウェアを持っていない: enter image description here

なぜ私は2枚のネットワークカードの一つだけからのトラフィックを取得していますか?

EDIT

私も次のことを試してみました:

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); 
       } 
      } 
     }); 
    } 
} 

私は二回(私の2つのIP用)「theCorrectIPリッスンするように開始」を参照してください、それはまだ来てデータだけを表示します1つのネットワークカードから。私はあまりにも奇妙である何かを気づかなかった

EDIT 2

。すべてのデータを受信したインターフェイスを無効にしてソフトウェアを起動すると、もう一方のインターフェイスからデータが取得されます。インターフェイスを再度アクティブにしてソフトウェアを再起動すると、非アクティブ化されていないカードにトラフィックが残ります。

そして私は、私は1つのネットワークのみ(両方ではない)に接続されている私には対応機器を、したことを確かに知って

EDIT 3

もう一つは:私は、メッセージを送信する場合私(localhost)から、私が持っているすべてのネットワークカードで、私はそれらが私の2つのネットワークインターフェイスに来るのを見ます。しかし、プログラムを2回起動すると、最初のプログラムだけがメッセージを取得し、2回目は取得しません。

編集4

最初のコメント以下の追加情報、: 私は2枚のイーサネットカード、10.10.24.78 IPを持つ1、10.9.10.234 IPと他をしました。 これは、データを送信する私ではありませんが、ネットワークピース(このIPのポート5353はmDNSのために使用するマルチキャストアドレスを知っているので、私は、プリンタ、iTunesの、マックのようなものからのトラフィックを受信する必要があり、およびソフトウェアのいくつかの他の作品は、私たちが作成しました) 。データは、IP 224.0.0.251とポート5353にマルチキャストされています。ここで

あなたはseveralsのIPアドレスにデータを送信するために使用することができたコードですが、(一つだけのローカルクライアントがメッセージを受け取ることを除いて)それはほとんど動作しますローカルでそれを開始した場合のように、私は、説明しました。

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); 
     } 
    } 
} 

EDITここ5 は、(そのコマンドを知らなかった)私のroute printの結果であり、そして私の2つのIP上で、私は常に編集6 10.9.10.234 enter image description here

上のデータを受信

は、私はいくつかの他のものを試してみました:

    >働いていませんでした
  1. MulticastInterfaceを指定 - >
  2. はリーダー(dontrouteは= 1、放送= 1)の上にいくつかの追加のsocketOptionを設定して働いていませんでした -
  3. ではなくUdpClientの受信にソケットを使用します(socketOption MulticastInterfaceを使用して)リーダーソケットが使用する必要があります - >動作しませんでした。
+0

あなたのインターフェイス(ethernet、eth/wlan)は何ですか?そして、これらのインターフェース上でどのようなIPを持っていますか?マルチキャストメッセージの送信方法を分析できると便利です。 – PCoder

+0

@PCoder:ご意見ありがとうございました。私の最初の質問(編集4)の詳細を追加しました – J4N

+0

'route print'コマンドの出力を表示できますか? – PCoder

答えて

5

私は最終的にそれを行う方法を見つけました!

実際には、同じコードをそのまま使用しても、非同期メソッドで使用すると機能します。私はちょうどそれが同期方法で動作しない理由を理解できません(もし誰かが知っていれば、私に教えてもらえます:))

私はこれを3日間失ってしまったので、 :

private static void ReceiveAsync(int port, string address, IEnumerable<IPAddress> localAddresses) 
{ 
    IPAddress multicastAddress = IPAddress.Parse(address); 
    foreach (IPAddress localAddress in localAddresses) 
    { 
     var udpClient = new UdpClient(AddressFamily.InterNetwork); 
     udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 
     udpClient.Client.Bind(new IPEndPoint(localAddress, port)); 
     udpClient.JoinMulticastGroup(multicastAddress, localAddress); 
     udpClient.BeginReceive(OnReceiveSink, 
           new object[] 
            { 
             udpClient, new IPEndPoint(localAddress, ((IPEndPoint) udpClient.Client.LocalEndPoint).Port) 
            }); 
    } 
} 

そして非同期メソッド:私はそれが役に立てば幸い

private static void OnReceiveSink(IAsyncResult result) 
{ 
    IPEndPoint ep = null; 
    var args = (object[]) result.AsyncState; 
    var session = (UdpClient) args[0]; 
    var local = (IPEndPoint) args[1]; 

    byte[] buffer = session.EndReceive(result, ref ep); 
    //Do what you want here with the data of the buffer 

    Console.WriteLine("Message received from " + ep + " to " + local); 

    //We make the next call to the begin receive 
    session.BeginReceive(OnReceiveSink, args); 
} 

;)

2

利用可能なすべてのインターフェイスでマルチキャストグループに参加する必要があります。デフォルトでは、発信IGMP JOINメッセージは、ユニキャストルーティングテーブルに従ってルーティングされます。ユニキャストルーティングテーブルは、そのルートにアクセスするNICを使用して、「最も安い」ルート経由で送信します。マルチキャストグループが複数のルート経由で供給される場合は、反復する必要があります。

+0

すべてのUdpClientに対して行われている 'mUdpClientReceiver.JoinMulticastGroup(IPAddress.Parse(ip)、255);'は理解できません。いいえ、どうすればいいですか? – J4N

+0

ローカルインターフェイスのIPアドレスを繰り返し処理し、それぞれを経由して参加する必要があります。 – EJP

+1

私はあなたが私の2番目のコード引用符を見なかったと思います。それはまさに私がやっていることです。 – J4N

2

私はすべての私のネットワークインターフェイスからマルチキャストを受信したかった同じ問題を抱えていました。 EJPは、すでに述べたように、あなたはすべてのネットワークインタフェースのためのUdpClientにJoinMulticastGroup(IPAddress multicastAddr, IPAddress localAddress)を呼び出す必要があります:私はすべてのネットワークインタフェース上で私のマルチキャストを送信することができますので、私もUdpClientsのリストを作成してい

int port = 1036; 
IPAddress multicastAddress = IPAddress.Parse("239.192.1.12"); 

client = new UdpClient(new IPEndPoint(IPAddress.Any, port)); 

// list of UdpClients to send multicasts 
List<UdpClient> sendClients = new List<UdpClient>(); 

// join multicast group on all available network interfaces 
NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); 

foreach (NetworkInterface networkInterface in networkInterfaces) 
{ 
    if ((!networkInterface.Supports(NetworkInterfaceComponent.IPv4)) || 
     (networkInterface.OperationalStatus != OperationalStatus.Up)) 
    { 
     continue; 
    } 

    IPInterfaceProperties adapterProperties = networkInterface.GetIPProperties(); 
    UnicastIPAddressInformationCollection unicastIPAddresses = adapterProperties.UnicastAddresses; 
    IPAddress ipAddress = null; 

    foreach (UnicastIPAddressInformation unicastIPAddress in unicastIPAddresses) 
    { 
     if (unicastIPAddress.Address.AddressFamily != AddressFamily.InterNetwork) 
     { 
      continue; 
     } 

     ipAddress = unicastIPAddress.Address; 
     break; 
    } 

    if (ipAddress == null) 
    { 
     continue; 
    } 

    client.JoinMulticastGroup(multicastAddress, ipAddress); 

    UdpClient sendClient = new UdpClient(new IPEndPoint(ipAddress, port)); 
    sendClients.Add(sendClient); 
} 

+0

Thnks、これは役に立ちました – KGCybeX

関連する問題