【问题标题】:C# UDP Socket Bind ExceptionC# UDP 套接字绑定异常
【发布时间】:2023-03-23 04:15:02
【问题描述】:

我正在尝试为无线网状网络创建一个程序(除名称外都是 adhoc)。大多数网络将处理 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。这是一个无效的参数,但我对这意味着什么感到困惑,因为所需的参数是一个端点。

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

【问题讨论】:

    标签: c# .net sockets udpclient mesh-network


    【解决方案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。如果您尝试使用它,这可能会导致问题。

    【讨论】:

    • 我对任何 TCP/UDP/Socket 的任何事情都是 95% 的新手,所以我已经盲目地飞行了大约 2 周来弄清楚这一点。使用 EndPoint 创建 UdpClient 后,我​​将 Socket 绑定到辅助 Endpoint?
    • 上面的逻辑(我的版本)将套接字绑定到那个端点,然后在端点上设置一个客户端——套接字仍然在那个点绑定。您也可以使用端口 id = 0,系统将使用任何可用的本地端口,在endPoint1 上该选项可能对您来说更容易。在此处查看 MSDN 上的示例代码 - msdn.microsoft.com/en-us/library/k227d11f.aspx - 有大量示例可以帮助您解决这个问题。在这里查看一般 TCP/UDP 入门信息 - msdn.microsoft.com/en-us/library/c19ex43h.aspx
    • 我在测试时创建了大量类似的变量——只是在最后给它们不同的数字,以便在测试时快速选择它们。至于程序-我根据您的建议对其进行了更改,尝试了第一个,然后尝试了第二个,最后使用 0 作为 UdpClient 的端口。我再次收到与 socket.Bind 相同的错误代码。
    • 想通了,UDP 不允许绑定或其他东西。
    • @Scott S - 很高兴听到您对此感到满意
    【解决方案2】:

    我同意史蒂夫的观点。但是,您声明

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

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

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

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

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

    罗伯托

    【讨论】:

    • 如果您想从特定端口发送也很有用,即使您绑定到 IPAddress.Any。
    猜你喜欢
    • 2015-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多