gpt4 book ai didi

c# - UDP:从所有网络接口(interface)读取数据

转载 作者:太空狗 更新时间:2023-10-29 21:05:15 24 4
gpt4 key购买 nike

我有以下代码来读取来自网络的多播消息,用于指定的 IP+端口

private static void ReceiveMessages(int port, string ip, CancellationToken token)
{
Task.Factory.StartNew(() =>
{
using (var mUdpClientReceiver = new UdpClient())
{
var mReceivingEndPoint = new IPEndPoint(IPAddress.Any, port);
mUdpClientReceiver.ExclusiveAddressUse = false;
mUdpClientReceiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
mUdpClientReceiver.ExclusiveAddressUse = false;
mUdpClientReceiver.Client.Bind(mReceivingEndPoint);
mUdpClientReceiver.JoinMulticastGroup(IPAddress.Parse(ip), 255);

while (!token.IsCancellationRequested)
{
byte[] receive = mUdpClientReceiver.Receive(ref mReceivingEndPoint);

Console.WriteLine("Message received from {0} ",mReceivingEndPoint);
}
}
});
}

我有两个网络适配器,我的数据来自这个多播 ip+端口(由监控每个网络适配器的两个 wireshark 实例确认)。我在 wireshark 上看到两个网卡的这些端口 + Ip 上有很多流量。

问题是在我的控制台上,我只能看到来自一张网卡的消息。

我仔细检查了 netstat,我没有任何其他软件在我的端口上监听: enter image description here

那么为什么我的流量只来 self 的两个网卡中的一个?

编辑:

我什至尝试了以下方法:

private static void ReceiveMessages(int port, string ip, CancellationToken token, IEnumerable<IPAddress> ipAddresses)
{
foreach (IPAddress ipAddress in ipAddresses)
{
IPAddress ipToUse = ipAddress;
Task.Factory.StartNew(() =>
{
using (var mUdpClientReceiver = new UdpClient())
{

var mReceivingEndPoint = new IPEndPoint(ipToUse, port);
mUdpClientReceiver.ExclusiveAddressUse = false;
mUdpClientReceiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
mUdpClientReceiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
mUdpClientReceiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, 1);
mUdpClientReceiver.ExclusiveAddressUse = false;
mUdpClientReceiver.Client.Bind(mReceivingEndPoint);
mUdpClientReceiver.JoinMulticastGroup(IPAddress.Parse(ip), 255);
Console.WriteLine("Starting to listen on "+ipToUse);
while (!token.IsCancellationRequested)
{
byte[] receive = mUdpClientReceiver.Receive(ref mReceivingEndPoint);

Console.WriteLine("Message received from {0} on {1}", mReceivingEndPoint,ipToUse);
}
}
});
}
}

我两次看到“Starting to listen on theCorrectIP”(对于我的两个 IP),但它仍然只显示来自一张网卡的数据。

编辑 2

我也确实注意到了一些奇怪的事情。如果我禁用接收所有数据的接口(interface),然后启动软件,我现在从另一个接口(interface)获取数据。如果我再次激活接口(interface)并重新启动软件,我仍然可以获得未停用卡上的流量。

而且我确信我的设备对我有响应,它们只连接到一个网络(不是两个)

编辑 3

另一件事:如果我从我(本地主机)发送一条消息,在我拥有的所有网卡上,我会看到它们出现在我的两个网络接口(interface)上。但是,如果我启动我的程序两次,只有第一个程序会收到消息,第二个不会。

编辑4

附加信息,在第一条评论之后:我有两张以太网卡,一张是 10.10.24.78 ip,另一张是 10.9.10.234 ip。发送数据的不是我,而是网络片段(带有此 ip 的端口 5353 是用于 mDNS 的已知多播地址,因此我应该从打印机、itunes、macs 和其他一些东西接收流量我们创建的软件)。数据在ip上多播 224.0.0.251 和端口 5353

这是一个代码,您可以使用它在多个 IP 上发送数据,但正如我所描述的,如果您在本地启动它,它几乎可以工作(除了只有一个本地客户端接收消息)。

private static void SendManuallyOnAllCards(int port, string multicastAddress, IEnumerable<IPAddress> ipAddresses)
{
foreach (IPAddress remoteAddress in ipAddresses)
{
IPAddress ipToUse = remoteAddress;
using (var mSendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
{
mSendSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership,
new MulticastOption(IPAddress.Parse(multicastAddress)));
mSendSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 255);
mSendSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

var ipep = new IPEndPoint(ipToUse, port);
//IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(multicastAddress), port);
mSendSocket.Bind(ipep);
mSendSocket.Connect(ipep);


byte[] bytes = Encoding.ASCII.GetBytes("This is my welcome message");
mSendSocket.Send(bytes, bytes.Length, SocketFlags.None);
}
}
}

编辑 5这是我的 route print(不知道该命令)的结果,在我的两个 IP 上,我总是在 10.9.10.234 上接收数据 enter image description here

编辑6

我尝试了其他几种方法:

  1. 使用套接字代替 UdpClient 来接收 --> 没用
  2. 在阅读器上设置一些额外的 socketOption(DontRoute =1, Broadcast=1) -->没用
  3. 指定读取器 Socket 必须使用的 MulticastInterface(使用 socketOption MulticastInterface)--> 没用

最佳答案

我遇到了同样的问题,我想从我的所有网络接口(interface)接收多播。正如 EJP 已经说过的,您需要在所有网络接口(interface)的 UdpClient 上调用 JoinMulticastGroup(IPAddress multicastAddr, IPAddress localAddress):

int port = 1036;
IPAddress multicastAddress = IPAddress.Parse("239.192.1.12");

client = new UdpClient(new IPEndPoint(IPAddress.Any, port));

// list of UdpClients to send multicasts
List<UdpClient> sendClients = new List<UdpClient>();

// join multicast group on all available network interfaces
NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();

foreach (NetworkInterface networkInterface in networkInterfaces)
{
if ((!networkInterface.Supports(NetworkInterfaceComponent.IPv4)) ||
(networkInterface.OperationalStatus != OperationalStatus.Up))
{
continue;
}

IPInterfaceProperties adapterProperties = networkInterface.GetIPProperties();
UnicastIPAddressInformationCollection unicastIPAddresses = adapterProperties.UnicastAddresses;
IPAddress ipAddress = null;

foreach (UnicastIPAddressInformation unicastIPAddress in unicastIPAddresses)
{
if (unicastIPAddress.Address.AddressFamily != AddressFamily.InterNetwork)
{
continue;
}

ipAddress = unicastIPAddress.Address;
break;
}

if (ipAddress == null)
{
continue;
}

client.JoinMulticastGroup(multicastAddress, ipAddress);

UdpClient sendClient = new UdpClient(new IPEndPoint(ipAddress, port));
sendClients.Add(sendClient);
}

我还创建了一个 UdpClient 列表,这样我就可以在所有网络接口(interface)上发送我的多播。

关于c# - UDP:从所有网络接口(interface)读取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15265620/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com