1

我正在尝试为无线网状网络创建一个程序(除了名称之外的所有内容)。大多数网络将处理 TCP 消息传递,但要确定所有邻居 IP(因为它们在启动时将是未知的),我选择使用 UDP 广播作为初始发现消息。在大多数情况下,该代码是无关紧要的,因为初始测试似乎有效,目前我不调用它。

以下是接收和注册邻居IP的部分。

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

我已经使用两个 IPEndPoints 进行了测试,无论我如何设置它,绑定都会失败,并出现 SocketException.ErrorCode 10022 Windows Socket Error Codes。这是一个无效的参数,但我对这意味着什么感到困惑,因为所需的参数是一个端点。

这在第一次运行时失败,所以它不像我试图重新绑定端口。

4

2 回答 2

1

您已经将端口绑定到UdpCLient构建它的时候。然后,您不能将同一端口绑定到单独的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

如果你想这样做,构建和绑定IPEndPoint然后UdpClient用它而不是端口来构建。

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

我不确定您为什么还要endPoint1在同一个端口上设置另一个端点。如果您尝试使用它,这可能会导致问题。

于 2010-11-09T23:32:55.183 回答
1

我同意史蒂夫。但是,你说

“UDP 不允许绑定或其他东西。”

但确实如此。您可以将任何套接字(udp 与否)绑定到任何网络接口。史蒂夫给出了实现它的提示。我就是这样做的:

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

正如 steve 所指出的,一旦 UdpClient 被实例化,它就不允许重新绑定到另一个接口。诀窍是告诉构造函数事先绑定到你想要的接口。替换为您希望使用的本地接口的 IP 地址。

当然,这仅在您拥有(或可能拥有)多个网络接口并希望使用特定网络接口时才有用。否则,我已经看到具有有效互联网网关的接口通常是客户端默认绑定的接口。这通常是正确的。

罗伯托

于 2013-08-22T23:35:49.103 回答