Questo è in realtà più complicato di quanto possa sembrare, perché se si dispone di più di un'interfaccia, le trasmissioni non si diffonderanno sempre su tutte le interfacce. Per aggirare questo ho creato questa classe.
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);
}
}
Quindi per inviare il pacchetto UDP via broadcast, io uso qualcosa come il seguente. Sto usando IPAddress.Broadcast
e MyUdpClient
, che è diverso dal tuo codice.
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);
Inoltre, si dovrebbe notare che quando si utilizza una specifica ipaddress
invece di trasmissione della tabella di route invia solo fuori l'interfaccia che corrisponde all'indirizzo.
Così nel tuo esempio, viene usato unicast. È necessario impostare LocalIP
sull'IP dell'interfaccia locale a cui si desidera inviare. Con tre interfacce, avresti tre IP locali e devi scegliere quello corretto da utilizzare.
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);
Perché percorso è spento si potrebbe vedere su tutte le interfacce, ma sarà necessario per testare questo per il caso unicast.
Se non ti interessa l'IP o la porta di invio, puoi utilizzare il seguente codice.
IPEndPoint targetEndPoint = new IPEndPoint(TargetIP, iTargetPort);
MyUdpClient sendUdpClient = new MyUdpClient();
int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint);
o per la trasmissione
IPEndPoint targetEndPoint = new IPEndPoint(IPAddress.Broadcast, iTargetPort);
MyUdpClient sendUdpClient = new MyUdpClient();
int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint);
Il problema con IPAddress.Broadcast
è che non lo faranno percorso attraverso qualsiasi gateway. Per aggirare questo è possibile creare un elenco di IPAddresses
e quindi eseguire il ciclo e inviare. Inoltre, poiché Send può fallire per problemi di rete che non puoi controllare, dovresti anche avere un blocco 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
}
Edit: vedi sopra cambiamento trasmettere in unicast con interfacce multiple e anche Problem Trying to unicast packets to available networks.
Può chiarire di più ciò che si sta tentando desidera to-do. –
La mia applicazione invierà messaggi a un'applicazione in più di 10 sistemi. In cui tutti i sistemi sono in tre diverse schede di rete. Come 10.1.x.x/10.2.x.x/10.4.x.x sono in grado di ricevere il messaggio in una sola scheda di rete 10.1.x.x ma non in altre due schede di rete. Quindi voglio verificare la disponibilità della scheda di rete e quindi inviare il messaggio. Grazie. – Anuya
quindi il messaggio deve solo verificare la disponibilità della rete o ha qualche altro payload/significato? –