c# - 发送广播包问题

标签 c# android sockets network-programming

我目前正在从事 C#/Android 客户端/服务器项目。

我有一个服务器应用程序,在 Windows 上运行 C#,它在端口 8000 上发送广播消息。

想法是客户端应用程序 (Android) 接收广播,然后根据通过广播发送的消息在 Android 设备上显示服务器主机名和 IP 以供用户选择。

下面是我尝试进行广播的方式。

int availableTCPSocket = 0;
            try
            {
                //UdpClient udp = new UdpClient();
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
                availableTCPSocket = getAvailableTCPSocket();

                //IPEndPoint endpoint = new IPEndPoint(IPAddress.Broadcast, BROADCAST_PORT);
                IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("192.168.1.255"), BROADCAST_PORT);

                XmlGenerator xmlGenerator = new XmlGenerator();
                xmlGenerator.addStartElement("ServerInformation");
                xmlGenerator.addElementString("Hostname", Dns.GetHostName());
                NetworkAdapterDetails networkAdapterDetails = getNetworkAdapterDetails();
                xmlGenerator.addElementString("IP_Address", networkAdapterDetails.ipAddress);
                xmlGenerator.addElementString("MAC_Address", networkAdapterDetails.macAddress);
                xmlGenerator.addElementString("AvailableTCPSocket", availableTCPSocket.ToString());
                xmlGenerator.addEndElement();
                xmlGenerator.flushAndCloseXmlWriter();

                string udpData = xmlGenerator.returnXml();
                byte[] sendBytes = Encoding.ASCII.GetBytes(udpData);

                while (true)
                {
                    //udp.Send(sendBytes, sendBytes.Length, endpoint);
                    socket.SendTo(sendBytes, endpoint);
                    Console.WriteLine("Broadcast Sent");
                    System.Threading.Thread.Sleep(5000);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Broadcast Sender Exception: {0}", ex.Message);
            }

如果我将端点设置为 IPAddress.Broadcast,它表示它是 255.255.255.255,但我的设备从未接收到广播。

如果我将要硬编码的端点更改为 192.168.1.255,那么我的设备会收到广播。

因此,我有两个问题。

  1. 如果我使用 IPAddress.Broadcast,为什么我的设备收不到应该广播的任何内容。

  2. 如果 192.168.1.255 是正确的广播地址,我如何动态找出地址应该是什么,想法是服务器将提供下载所以必须在不同的网络配置上工作,其中 192.168.1.255可能不是正确的地址。

设备接收数据包也需要很长时间,服务器每次循环都会写入控制台并发送广播,但在设备接收之前大约需要发送 4 或 5 个广播。它位于 WiFi 网络上,但所有设备上的信号都很强,互联网上的下载速度为 60mb,路由器和设备之间的 ping 速度为 2ms。

最佳答案

Windows 7 以不同的方式处理 255.255.255.255 广播。更多信息 here: Send UDP broadcast on Windows 7

使用子网广播代替 255.255.255.255

获取子网广播地址的代码

public static IPAddress GetBroadcastAddress(this IPAddress address, IPAddress subnetMask)
{
    byte[] ipAdressBytes = address.GetAddressBytes();
    byte[] subnetMaskBytes = subnetMask.GetAddressBytes();

    if (ipAdressBytes.Length != subnetMaskBytes.Length)
        throw new ArgumentException("Lengths of IP address and subnet mask do not match.");

    byte[] broadcastAddress = new byte[ipAdressBytes.Length];
    for (int i = 0; i < broadcastAddress.Length; i++)
    {
        broadcastAddress[i] = (byte)(ipAdressBytes[i] | (subnetMaskBytes[i] ^ 255));
    }
    return new IPAddress(broadcastAddress);
}

关于c# - 发送广播包问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24295650/

相关文章:

c - 通过c中的套接字发送结构

c# - ASP.net Identity SecurityStampValidator OnValidateIdentity regenerateIdentity 参数

c# - 是否可以将 C#11 'required' 修饰符用于 .NET Framework 4.8 和 .Net Standard 2.0?

java - 打开街道 map (osmdroid) 在 PC 中显示灰色瓷砖而不是 map

java - Service 内部的 Handler 和 Thread 一直在运行,而 Service 似乎已经停止

python - 循环在 socket.connect_ex() 中不起作用

c# - 如何在服务器端处理新的刷新 token ?

c# - Console.WriteLine ("text"+ 函数(参数));不起作用,但该指令分为两个 Console.Write 工作正常

android - Android Wear 是否支持动画

java - Android Socket TCP 数据丢失