问题描述
我需要向特定的 IP 和端口发送 UDP 消息.
I need to send a UDP message to specific IP and Port.
由于有3个网卡,
10.1.x.x
10.2.x.x
10.4.x.x
当我发送 UDP 消息时,我只在一个网络适配器中接收到消息...其余的 ip 没有接收到.
when i send a UDP message,i am receiving the message only in one network adapter...the rest of the ip's are not receiving.
我想在发送消息时检查网络适配器.我该怎么做?
I want to check for the network adapter while sending the message. How can I do that?
目前我正在使用以下内容:
Currently I am using the following:
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);
推荐答案
这实际上比听起来更棘手,因为如果您有多个接口,则广播不会总是发送到所有接口.为了解决这个问题,我创建了这个类.
This is actually trickier than it sounds because if you have more than one interface the broadcasts will not always go out to all the interfaces. To get around this I created this class.
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
,这与您的代码不同.
Then to send the UDP packet via broadcast, I use something like the following. I am using IPAddress.Broadcast
and MyUdpClient
, which is different from your code.
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
而不是广播时,路由表只会将其发送到与地址匹配的接口.
Also, you should note that when you use a specific ipaddress
instead of broadcast the route table only sends it out the interface that matches the address.
因此,在您的示例中,使用了单播.您需要将 LocalIP
设置为要发送到的本地接口的 IP.使用三个接口,您将拥有三个本地 IP,您需要选择正确的一个来使用.
So in your example, unicast is used. You need to set LocalIP
to the IP of the local interface you want to send out to. With three interfaces, you would have three local IP's and you need to pick the correct one to use.
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);
由于路由已关闭,您可能会在所有接口上看到它,但您需要针对单播情况进行测试.
Because route is turned off you might see it on all interfaces but you will need to test this for the unicast case.
如果您不关心发送 IP 或端口,您可以使用以下代码.
If you don't care about the send IP or port you can use the following code.
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 块.
The problem with IPAddress.Broadcast
is that they will not route through any gateways. To get around this you can create a list of IPAddresses
and then loop through and send. Also since Send can fail for network issues that you cannot control you should also have a try/catch block.
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
}
请参阅上面更改为具有多个接口的单播以及 尝试将数据包单播到可用网络时出现问题.
see above change to unicast with multiple interfaces and also Problem Trying to unicast packets to available networks.
这篇关于向所有可用的网卡广播 UDP 消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!