UDP: ler dados de todas as interfaces de rede
Eu tenho o seguinte código para ler mensagens multicast provenientes da rede, para um IP + porta especificado
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);
}
}
});
}
Eu tenho dois adaptador de rede a partir do qual eu recebo dados sobre este multicast ip + port (confirmado por duas instâncias de wireshark monitorando cada adaptador de rede). Eu vejo em wireshark um monte de tráfego vindo dessas portas + Ip) para ambas as placas de rede.
O problema é que no meu console, só vejo mensagens provenientes de uma placa de rede.
Eu verifiquei novamente com netstat, eu não tenho nenhum outro software de escuta na minha porta:
Então, por que estou recebendo tráfego de apenas uma das minhas duas placas de rede?
EDITAR:
Eu até tentei o seguinte:
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);
}
}
});
}
}
Eu vejo o "Começando a escutar no theCorrectIP" duas vezes (para meus dois IPs), mas ainda exibe apenas os dados provenientes de uma placa de rede.
EDIT 2
Eu notei algo mais que é estranho também. Se eu desabilitar a interface na qual recebo todos os dados e, em seguida, iniciar o software, agora obtenho os dados da outra interface. Se eu ativar novamente a interface e reiniciar o software, ainda receberei o tráfego no cartão não desativado.
E eu sei com certeza que tenho dispositivos que respondem a mim, que estão conectados apenas a uma rede (não a ambos)
EDITAR 3
Outra coisa: se eu enviar uma mensagem de mim (localhost), em todas as placas de rede que eu tenho, vejo-as chegando em minhas duas interfaces de rede. MAS, se eu iniciar meu programa duas vezes, somente o primeiro programa receberá mensagens, não o segundo.
Editar 4
Informações adicionais, após o primeiro comentário: Eu tenho duas placas ethernet, uma com a10.10.24.78
ip, o outro com o10.9.10.234
ip. Não sou eu quem envia dados, mas pedaços de rede (a porta5353
com este ip é um endereço de multicast conhecido usado para mDNS, então eu deveria receber tráfego de coisas como impressora, itunes, macs e alguns outros softwares que criamos). Os dados são multicasts no ip224.0.0.251
e porta5353
.
Aqui está um código que você poderia usar para enviar dados em vários IPs, mas, como descrevi, se você iniciá-lo em local, ele quase funciona (exceto que apenas um cliente local recebe a mensagem).
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 Aqui está o resultado do meuroute print
(Não sabia esse comando), e nos meus dois IPs, sempre recebo dados sobre o10.9.10.234
Editar 6
Eu tentei várias outras coisas:
Use um soquete para receber em vez do UdpClient -> Não funcionouDefinir alguma adição socketOption no leitor (DontRoute = 1, Broadcast = 1) -> Não funcionouEspecifique o MulticastInterface que o leitor Socket tem que usar (usando socketOption MulticastInterface) -> Não funcionou