开发者

C# UDP Socket Bind Exception

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开发者_StackOverflow 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.


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.


I agree with steve. However, you state that

"UDP doesn't allow binding or stuff."

But it does. You can bind any socket (udp or not) to any network interface. Steve gave a hint to achieve it. This is how I do it:

LocalEP = new IPEndPoint(<local IP>, _PORTRECEIVE) ;
listener = New UdpClient(LocalEP) ;

As steve pointed out, once an UdpClient is instantiated, it does not allow rebinding to another interface. The trick is telling the constructor to bind to de interface you want beforehand. Substitute by the IP address of the local interface you wish to use.

Sure, this is only useful when you have (or might have) several network interfaces and want to use a specific one. Otherwise, I've seen that the interface with a valid gateway to the internet is usually the one to which clients bind by default. And this is usually the correct one.

Roberto

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜