2010-02-03 8 views
9

En una computadora con una tarjeta inalámbrica activa y un puerto LAN con un cable cruzado conectado a otra máquina que ejecute la misma aplicación, debemos enviar un UDP Multidifusión a través del cable LAN a la otra computadora. Usando Sockets C#, Windows parece intentar enrutar el mensaje a través del adaptador WLAN todo el tiempo.Especificar a qué interfaz de red debe conectarse una multidifusión UDP en .NET

¿Hay alguna manera de especificar qué interfaz de red debe enviar una multidifusión UDP?

+1

¿Encontró una solución? Tengo el mismo problema. ¿El artículo en MSDN resolvió su problema? – Gobliins

+0

para mí no lo hizo – Gobliins

+0

@Gobliins No funcionó para mí también:/¿Alguna solución? – J4N

Respuesta

5

Probablemente estás buscando SocketOptionName.MulticastInterface. Here es un artículo en MSDN que podría ayudarlo.

Aparte de eso, si actualiza su tabla de enrutamiento local para tener una entrada exacta que coincida con la dirección de multidifusión y apunte a la interfaz correcta, debería funcionar.

10

Al igual que una adición a Nikolai respuesta: el problema con KB318911 es un truco sucio que el usuario debe proporcionar el índice de adaptador necesario. Mientras mira cómo recuperar este índice de adaptadores me di cuenta de tales receta:

NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces(); 
foreach (NetworkInterface adapter in nics) 
{ 
    IPInterfaceProperties ip_properties = adapter.GetIPProperties(); 
    if (!adapter.GetIPProperties().MulticastAddresses.Any()) 
    continue; // most of VPN adapters will be skipped 
    if (!adapter.SupportsMulticast) 
    continue; // multicast is meaningless for this type of connection 
    if (OperationalStatus.Up != adapter.OperationalStatus) 
    continue; // this adapter is off or not connected 
    IPv4InterfaceProperties p = adapter.GetIPProperties().GetIPv4Properties(); 
    if (null == p) 
    continue; // IPv4 is not configured on this adapter 

    // now we have adapter index as p.Index, let put it to socket option 
    my_sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)IPAddress.HostToNetworkOrder(p.Index)); 
} 

nota completa en http://windowsasusual.blogspot.ru/2013/01/socket-option-multicast-interface.html

+0

Lone link es [considerada como una respuesta pobre] (http://stackoverflow.com/faq#deletion) ya que no tiene sentido por sí mismo y ** no se garantiza que el recurso objetivo esté vivo en el futuro **. [Sería preferible] (http://meta.stackexchange.com/q/8259) incluir aquí las partes esenciales de la respuesta y proporcionar el enlace de referencia. – j0k

+0

Fxied, muchas gracias –

+0

Gracias; 'adapter.SupportsMulticast' es útil para conocer. NOTA: 'p.Index' a veces es' -1' para loopback local, cuando debería ser '1'. y 'p.Index' tira si el adaptador no tiene ningún índice. –

2

Dependiendo de lo que está haciendo, hay un método Win32 que podría ayudar. Devolverá la mejor interfaz para una dirección IP determinada. Para obtener el uno por defecto (la 0.0.0.0), que suele ser lo que quiere para multidifusión, que es bastante fácil:

P/Invoke firma:

[DllImport("iphlpapi.dll", CharSet = CharSet.Auto)] 
private static extern int GetBestInterface(UInt32 DestAddr, out UInt32 BestIfIndex); 

Luego en otro lugar:

// There could be multiple adapters, get the default one 
uint index = 0; 
GetBestInterface(0, out index); 
var ifaceIndex = (int)index; 

var client = new UdpClient(); 
client.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)IPAddress.HostToNetworkOrder(ifaceIndex)); 

var localEndpoint = new IPEndPoint(IPAddress.Any, <port>); 
client.Client.Bind(localEndpoint); 

var multicastAddress = IPAddress.Parse("<group IP>"); 
var multOpt = new MulticastOption(multicastAddress, ifaceIndex); 
client.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, multOpt); 

var broadcastEndpoint = new IPEndPoint(IPAddress.Parse("<group IP>"), <port>); 
byte[] buffer = ... 
await client.SendAsync(buffer, buffer.Length, broadcastEp).ConfigureAwait(false); 
Cuestiones relacionadas