我需要向特定的IP和端口发送UDP消息.
由于有3张网卡,
10.1.x.x 10.2.x.x 10.4.x.x
当我发送UDP消息时,我只在一个网络适配器中收到消息...其余的ip没有收到.
我想在发送消息时检查网络适配器.我怎样才能做到这一点?
目前我正在使用以下内容:
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(LocalIP), 0); IPEndPoint targetEndPoint = new IPEndPoint(TargetIP, iTargetPort); UdpClient sendUdpClient = new UdpClient(localEndPoint); int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint);
Rex Logan.. 17
这实际上比它听起来更棘手,因为如果你有多个接口,广播将不会总是出现在所有接口上.为了解决这个问题,我创建了这个类.
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); } }
然后通过广播发送UDP数据包,我使用类似下面的内容.我使用IPAddress.Broadcast
和MyUdpClient
,这是从您的代码不同.
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);
此外,您应该注意,当您使用特定ipaddress
而不是广播时,路由表仅将其发送到与该地址匹配的接口.
因此,在您的示例中,使用单播.您需要设置LocalIP
要发送到的本地接口的IP.使用三个接口,您将拥有三个本地IP,您需要选择要使用的正确IP.
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);
由于路由已关闭,您可能会在所有接口上看到它,但您需要针对单播情况对其进行测试.
如果您不关心发送IP或端口,可以使用以下代码.
IPEndPoint targetEndPoint = new IPEndPoint(TargetIP, iTargetPort); MyUdpClient sendUdpClient = new MyUdpClient(); int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint);
或用于广播
IPEndPoint targetEndPoint = new IPEndPoint(IPAddress.Broadcast, iTargetPort); MyUdpClient sendUdpClient = new MyUdpClient(); int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint);
问题IPAddress.Broadcast
是他们不会通过任何网关.要解决此问题,您可以创建一个列表,IPAddresses
然后循环并发送.此外,由于发送可能因您无法控制的网络问题而失败,因此您还应该有一个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 }
编辑:请参阅上面的更改为具有多个接口的单播,还有问题尝试将数据包单播到可用网络.
这实际上比它听起来更棘手,因为如果你有多个接口,广播将不会总是出现在所有接口上.为了解决这个问题,我创建了这个类.
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); } }
然后通过广播发送UDP数据包,我使用类似下面的内容.我使用IPAddress.Broadcast
和MyUdpClient
,这是从您的代码不同.
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);
此外,您应该注意,当您使用特定ipaddress
而不是广播时,路由表仅将其发送到与该地址匹配的接口.
因此,在您的示例中,使用单播.您需要设置LocalIP
要发送到的本地接口的IP.使用三个接口,您将拥有三个本地IP,您需要选择要使用的正确IP.
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);
由于路由已关闭,您可能会在所有接口上看到它,但您需要针对单播情况对其进行测试.
如果您不关心发送IP或端口,可以使用以下代码.
IPEndPoint targetEndPoint = new IPEndPoint(TargetIP, iTargetPort); MyUdpClient sendUdpClient = new MyUdpClient(); int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint);
或用于广播
IPEndPoint targetEndPoint = new IPEndPoint(IPAddress.Broadcast, iTargetPort); MyUdpClient sendUdpClient = new MyUdpClient(); int numBytesSent = sendUdpClient.Send(CombineHeaderBody, CombineHeaderBody.Length, targetEndPoint);
问题IPAddress.Broadcast
是他们不会通过任何网关.要解决此问题,您可以创建一个列表,IPAddresses
然后循环并发送.此外,由于发送可能因您无法控制的网络问题而失败,因此您还应该有一个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 }
编辑:请参阅上面的更改为具有多个接口的单播,还有问题尝试将数据包单播到可用网络.