网络改变后UDP广播无法工作?

问题描述 投票:0回答:1

[预编码]

PC1(Windows): 局域网地址:10.0.1.11 无线网络地址:10.0.1.10

PC2(Windows): 无线网络地址:10.0.1.4

[一步一步我做了什么以及我得到了什么结果]

  1. 在禁用 WiFi 并启用 LAN 的情况下启动 PC1,我确认 IP 地址为 10.0.1.11
  2. 在启用 WiFi 的情况下启动 PC2,我确认 IP 地址是 10.0.1.4
  3. 在PC1上启动UDP广播程序(同时也在接收同一局域网内其他PC的UDP应答包);并启动PC2上的UDP接收器(收到广播消息后也回复广播发送者)
  4. 在PC1上启动Wireshark并捕获网络包。
  5. 在PC1上确认,收到PC2的响应消息。
  6. 禁用PC1上的LAN并启用其上的WiFi。并确认在UDP广播程序运行期间IP地址已更改为10.0.1.10(WiFi接口)。
  7. 过了一会儿,我在 PC1 上确认结果,它无法收到来自 PC2 的任何 UDP 响应。我还确认了 Wireshark 软件包,并且无法找到从 PC1 发送的任何广播消息(以过滤器“ip.proto==UDP && ip.src==10.0.1.10”或“ip.proto==UDP &&”为准) ip.src==10.0.1.11"!)。但是

发送广播消息的源码如下所示:

Socket sendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

// Use GetHostAddresses() to enumerate the local IPAddress
string hostName = Dns.GetHostName();
var addressList = Dns.GetHostAddresses(hostName);
foreach (var ip in addressList)
{
    if (ip.AddressFamily != AddressFamily.InterNetwork) { continue; }
    IPEndPoint ep = null;
    IPAddress ipSend = null;
    ipSend = IPAddress.Parse(ip.ToString());
    ipSend.Address |= 0xFF000000;
    ep = new IPEndPoint(ipSend, 1020);
    sendSocket.SendTo(broadcastMessage, ep);
}

//Use GetAllNetworkInterfaces() to enumerate the local IPAddress
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface adapter in nics)
{
  if (adapter.NetworkInterfaceType == NetworkInterfaceType.Ethernet ||
      adapter.NetworkInterfaceType == NetworkInterfaceType.Wireless80211)
  {
    IPInterfaceProperties ip = adapter.GetIPProperties();
    UnicastIPAddressInformationCollection ipCollection = ip.UnicastAddresses;
    foreach (UnicastIPAddressInformation ipadd in ipCollection)
    {
      if (ipadd.Address.AddressFamily == AddressFamily.InterNetwork)
      {
        IPEndPoint ep = null;
        IPAddress ipSend = null;
        ipSend = IPAddress.Parse(ipadd.Address.ToString());
        ipSend.Address |= 0xFF000000;
        ep = new IPEndPoint(ipSend, 1020);
        sendSocket.SendTo(broadcastMessage, ep);
      }
    }
  }
}

//Use GetHostEntry() to enumerate the local IPAddress
IPHostEntry host = Dns.GetHostEntry(hostName, AddressFamily.InterNetwork);
foreach (var ip in host.AddressList)
{
  IPEndPoint ep = null;
  IPAddress ipSend = null;
  ipSend = IPAddress.Parse(ip.ToString());
  ipSend.Address |= 0xFF000000;
  ep = new IPEndPoint(ipSend, 1020);
  sendSocket.SendTo(broadcastMessage, ep);
}

我尝试了3种方法来枚举本地IP地址,然后制作广播地址。但他们都失败了。

  1. 我还检查了 PC1 上的日志以了解 UDP 接收器部分。而且很奇怪的是,当我将PC1上的网络接口从LAN更改为WiFi后,我可以找到10.0.1.11(PC1的LAN接口IP)响应广播。 (据我了解,PC1的LAN已被禁用!)

看来,当网络从 LAN 变为 Wifi 后,SendTo() api 调用的广播消息没有经过 PC1 上的 TCP 层(否则 Wireshark 包会有信息)。

你们有关于这个问题的任何信息吗?提前非常感谢。

UDP接收器源代码如图所示。

socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
socket.Bind(new IPEndPoint(IPAddress.Any, 1020));
socket.ReceiveTimeout = 100;
_udpReceiver = new UdpClient{Client = socket};
_udpReceiver.Client.ReceiveBufferSize = 1024 * 1024;

endPoint = new IPEndPoint(IPAddress.Any, 0);
while (!_stopReceiveEvent.WaitOne(1))
{
  byte[] rawBytes = _udpReceiver.Receive(ref endPoint);
  if (rawBytes.Length <= 0){ continue; }
  string receivedDeviceIPAddr = endPoint.Address.ToString();
  Console.WriteLine($"Recieve UDP response from {receivedDeviceIPAddr} : {endPoint.Port}");
}        
c# wireshark broadcast
1个回答
0
投票

您不应该搞乱 DNS 名称和主机名。

而是从

IPAddress.Any
发送广播,并将其发送到
IPAddress.Broadcast

操作系统将选择最合适的适配器和原始地址来进行传输。

© www.soinside.com 2019 - 2024. All rights reserved.