To jest rzeczywiście trudniejsze, niż się wydaje, ponieważ jeśli masz więcej niż jeden interfejs, transmisje nie zawsze wychodzą na wszystkie interfejsy. Aby obejść ten problem, stworzyłem tę klasę.
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);
}
}
Następnie wysłać pakiet UDP za pośrednictwem transmisji używam coś jak poniżej. Używam IPAddress.Broadcast
i MyUdpClient
, która różni się od Twojego kodu.
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);
Ponadto, należy pamiętać, że podczas korzystania z konkretnego ipaddress
zamiast transmisji tabela trasa tylko wysyła go do interfejsu, który pasuje do adresu.
Tak więc w twoim przykładzie użyto unicast. Musisz ustawić LocalIP
na adres IP lokalnego interfejsu, do którego chcesz wysłać. Dzięki trzem interfejsom będziesz miał trzy lokalne adresy IP i musisz wybrać właściwy, którego chcesz użyć.
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);
Ponieważ trasa jest wyłączony można go zobaczyć na wszystkich interfejsach, ale trzeba będzie to sprawdzić w przypadku emisji pojedynczej.
Jeśli nie zależy Ci na wysłaniu adresu IP lub portu, możesz użyć następującego kodu.
IPEndPoint targetEndPoint = new IPEndPoint(TargetIP, iTargetPort);
MyUdpClient sendUdpClient = new MyUdpClient();
int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint);
lub audycji
IPEndPoint targetEndPoint = new IPEndPoint(IPAddress.Broadcast, iTargetPort);
MyUdpClient sendUdpClient = new MyUdpClient();
int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint);
problem z IPAddress.Broadcast
jest to, że nie będzie żadnej trasy przez bramy. Aby obejść ten problem, można utworzyć listę IPAddresses
, a następnie wykonać pętlę i wysłać. Także ponieważ Send może zawieść w przypadku problemów sieciowych, nad którymi nie możesz kontrolować, powinieneś także mieć blok 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: patrz wyżej zmianę do emisji pojedynczej z wielu interfejsów i również Problem Trying to unicast packets to available networks.
można wyjaśnić więcej czego chcą próby zrobienia. –
Moja aplikacja wyśle wiadomości do aplikacji w ponad 10 systemach. W którym wszystkie systemy są na trzech różnych kartach sieciowych. Podobnie jak 10.1.x.x/10.2.x.x/10.4.x.x mogę odebrać wiadomość tylko na jednej karcie sieciowej 10.1.x.x, ale nie na dwóch innych kartach sieciowych. Dlatego chcę sprawdzić dostępność karty sieciowej, a następnie wysłać wiadomość. Dzięki. – Anuya
, więc czy wiadomość ma tylko sprawdzić dostępność sieci, czy ma jakiś inny ładunek/znaczenie? –