1
votes

I am currently working on a C#/Android client/server project.

I have a server application, running C# on Windows, which sends a broadcast message on port 8000.

The idea is the client application (Android) receives the broadcast and then shows the server hostname and IP, from the message sent via the broadcast, on the Android device for the user to select.

Below is how I am attempting to do the broadcast.

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);
            }

If I set the endpoint to be IPAddress.Broadcast it says it is 255.255.255.255 but my devices never receive the broadcast.

If I change the endpoint to be hardcoded to 192.168.1.255 then my devices receive the broadcast.

So because of this I have two questions.

  1. If I use IPAddress.Broadcast why don't my devices receive anything if this is supposed to be broadcast.

  2. If 192.168.1.255 is the correct broadcast address, how can I find out what the addresss should be dynamically, the idea is the server will be provided for download so has to work on different network configurations where 192.168.1.255 might not be the correct address.

It also takes a long time for the device to receive the packet, the server writes to the console each time its looped round and sends the broadcast but it takes about 4 or 5 broadcasts to be sent before the devices receives it. Its on a WIFI network but strong signal on all devices, 60mb download on the internet and 2ms ping between router and devices.

Thanks for any help you can provide.

3

3 Answers

4
votes

Windows 7 handles 255.255.255.255 broadcast in a different way. More info here: Send UDP broadcast on Windows 7

use subnet broadcast instead of 255.255.255.255

Code to Get subnet broadcast address

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);
}
1
votes

You need to enable sending broadcast messages on the socket with socket.EnableBroadcast = true. Then you should be able to send them to 255.255.255.255 just fine.

Reference: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.enablebroadcast(v=vs.110).aspx

1
votes

Over wi-fi sometimes doesn't allow the packets send over 255.255.255.255 depending on the security settings in it. Find the broadcast address of the network at run time & use it. You can get the broadcast network address of any network by performing the below operation. broadcastaddress = (ipaddressofthesystem & netmask) & ~netmask; Also as an alternative you should consider using multicast address.