Esto es realmente más complicado de lo que parece, porque si tiene más de una interfaz, las transmisiones no siempre irán a todas las interfaces. Para evitar esto, creé esta clase.
public class MyUdpClient : UdpClient
{
public MyUdpClient() : base()
{
//Calls the protected Client property belonging to the UdpClient base class.
Socket s = this.Client;
//Uses the Socket returned by Client to set an option that is not available using UdpClient.
s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, 1);
}
public MyUdpClient(IPEndPoint ipLocalEndPoint) : base(ipLocalEndPoint)
{
//Calls the protected Client property belonging to the UdpClient base class.
Socket s = this.Client;
//Uses the Socket returned by Client to set an option that is not available using UdpClient.
s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, 1);
}
}
Luego, para enviar el paquete UDP por transmisión, utilizo algo como lo siguiente. Estoy usando IPAddress.Broadcast
y MyUdpClient
, que es diferente de su código.
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(LocalIP), 0);
IPEndPoint targetEndPoint = new IPEndPoint(IPAddress.Broadcast, iTargetPort);
MyUdpClient sendUdpClient = new MyUdpClient(localEndPoint);
int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint);
Además, debe tener en cuenta que cuando se utiliza un ipaddress
específica en lugar de la tabla de rutas de difusión sólo se envía fuera de la interfaz que coincide con la dirección.
Por lo tanto, en su ejemplo, se utiliza la unidifusión. Debe configurar LocalIP
en la IP de la interfaz local que desea enviar. Con tres interfaces, tendrías tres IP locales y necesitas elegir la correcta para usar.
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(LocalIP), 0);
IPEndPoint targetEndPoint = new IPEndPoint(TargetIP, iTargetPort);
MyUdpClient sendUdpClient = new MyUdpClient(localEndPoint);
int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint);
Como la ruta está desactivada, es posible que la vea en todas las interfaces, pero deberá probarla para el caso de unidifusión.
Si no le importa el IP o el puerto de envío, puede usar el siguiente código.
IPEndPoint targetEndPoint = new IPEndPoint(TargetIP, iTargetPort);
MyUdpClient sendUdpClient = new MyUdpClient();
int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint);
o para su difusión
IPEndPoint targetEndPoint = new IPEndPoint(IPAddress.Broadcast, iTargetPort);
MyUdpClient sendUdpClient = new MyUdpClient();
int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint);
El problema con IPAddress.Broadcast
es que no lo harán ruta a través de las puertas de enlace. Para evitar esto, puede crear una lista de IPAddresses
y luego recorrer y enviar. Además, dado que Send puede fallar por problemas de red que no puedes controlar, también debes tener un bloque try/catch.
ArrayList ip_addr_acq = new ArrayList();
ip_addr_acq.Add(IPAddress.Parse("10.1.1.1")); // add to list of address to send to
try
{
foreach (IPAddress curAdd in ip_addr_acq)
{
IPEndPoint targetEndPoint = new IPEndPoint(curAdd , iTargetPort);
MyUdpClient sendUdpClient = new MyUdpClient();
int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint);
Thread.Sleep(40); //small delay between each message
}
}
catch
{
// handle any exceptions
}
Editar: véase más arriba el cambio de unidifusión con múltiples interfaces y también Problem Trying to unicast packets to available networks.
Puede aclarar más lo que está intentando desea-do. –
Mi aplicación enviará mensajes a una aplicación en más de 10 sistemas. En el que todos los sistemas están en tres tarjetas de red diferentes. Como 10.1.x.x/10.2.x.x/10.4.x.x, puedo recibir el mensaje en una sola tarjeta de red 10.1.x.x pero no en otras dos tarjetas de red. Entonces quiero verificar la disponibilidad de la tarjeta de red y luego enviar el mensaje. Gracias. – Anuya
así es el mensaje solo para verificar la disponibilidad de la red, o tiene alguna otra carga/significado? –