C# UDP Socket Bind Exception

Scott S picture Scott S · Nov 10, 2010 · Viewed 7.9k times · Source

I am attempting to create a program for a wireless mesh (adhoc in all but name). Most of the network will deal with TCP messaging but to determine all neighbor IPs (as they will be unknown on startup), I choose to use UDP Broadcast for the initial discovery messages. That code, for the most part, is irrelevant as initial testing appeared to work and currently I do not call it.

The following is the section to receive and register the neighbors' IPs.

protected override void ReceiveMessageUDP()
    {
        while (live)
        {
            try
            {
                UdpListener = new UdpClient(_PORTRECEIVE);
                UdpListener.EnableBroadcast = true;
                Socket socket = UdpListener.Client;
                IPEndPoint endPoint1 = new IPEndPoint(IPAddress.Loopback, _PORTRECEIVE);
                IPEndPoint endPoint2 = new IPEndPoint(IPAddress.Any, _PORTRECEIVE);
                socket.Bind(endPoint2);
                socket.Listen(25);
                Socket connected = socket.Accept();
                byte[] buffer = new byte[1024];
                int length = connected.Receive(buffer);

                IPAddress remoteIP = ((IPEndPoint)connected.RemoteEndPoint).Address;
                if (!ipAddresses.Contains(remoteIP))
                    ipAddresses.Add(remoteIP);

                Message.Add(Encoding.ASCII.GetString(buffer, 0, length));
            }
            catch (SocketException e) { Console.WriteLine(e.ErrorCode); }
            catch (Exception) { }
        }
    }

I have tested with both IPEndPoints and regardless of how I set it up, the Bind fails with SocketException.ErrorCode 10022 Windows Socket Error Codes. It is an invalid argument but I am confused about what that means as the argument required is an EndPoint.

This fails on the first run so it's not like I am attempting to rebind the port.

Answer

Steve Townsend picture Steve Townsend · Nov 10, 2010

You've already bound the port to the UdpCLient when you constructed it. You cannot then bind the same port to a separate IPEndPoint.

UdpListener = new UdpClient(_PORTRECEIVE);  // binds port to UDP client
...
IPEndPoint endPoint2 = new IPEndPoint(IPAddress.Any, _PORTRECEIVE);
socket.Bind(endPoint2);  // attempts to bind same port to end point

If you want to do it this way, build and bind the IPEndPoint and then construct the UdpClient with it instead of the port.

IPEndPoint endPoint2 = new IPEndPoint(IPAddress.Any, _PORTRECEIVE);
socket.Bind(endPoint2);  // bind port to end point

UdpListener = new UdpClient(endPoint2);  // binds port to UDP client via endpoint

I am not sure why you are also setting up another end point endPoint1 on the same port. That will likely cause problems down the line, if and when you try to use this.