【问题标题】:UdpClient wont connect to IpAdress.AnyUdpClient 不会连接到 Ip Address.Any
【发布时间】:2019-04-19 01:06:29
【问题描述】:

我正在尝试侦听来自未知来源的 UDP 数据包。但无法绑定“未指定地址”(0.0.0.0 或 ::)

我已经尝试在 ::1 上收听。但从我测试的结果来看,这只适用于不通过网络接口的本地连接。

        public async void AwaitDiscoveryReply()
        {
            try
            {
                using (var client = new UdpClient(AddressFamily.InterNetworkV6))
                {
                    client.Connect(IPAddress.IPv6Any,4568);

                        var result = await client.ReceiveAsync();
                        Debug.WriteLine("Received DR");
                        var stateProtocol = StateProtocol.FromBytes(result.Buffer);
                        var robeatsDevice = new RobeatsDevice
                        {
                            Id = stateProtocol.DeviceId,
                            Name = stateProtocol.DeviceName,
                            EndPoint = client.Client.RemoteEndPoint,
                            StateProtocol = stateProtocol

                        };
                        OnDiscoveryReply(new DeviceDiscoveryEventArgs {RobeatsDevice = robeatsDevice});

                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
        }

这不断抛出异常:The requested address is not valid in its context [::]:4568

【问题讨论】:

  • 您使用的是 IPV4 还是 IPV6?
  • IPV6 但我认为在这种情况下这并不重要
  • 那么端口已经在使用中。尝试使用 from cmd.exe >Netstat -a 查看正在使用的端口。
  • jdweng - 如果地址已经绑定,错误消息会清楚地表明这一点。

标签: c# network-programming


【解决方案1】:

UDP 套接字是无连接的。 UDP 套接字实现上的“连接”方法,按照惯例(不要问我为什么)建立默认端点/过滤流量。如果你想从任何地址接收流量,你根本不需要“连接”。使用带有签名 UdpClient(Int32, AddressFamily) 的构造函数并删除 Connect() 调用:

public async void AwaitDiscoveryReply()
      {
          try
        {
            using (var client = new UdpClient(4568,AddressFamily.InterNetworkV6))
            {

                    var result = await client.ReceiveAsync();
                    Debug.WriteLine("Received DR");
                    var stateProtocol = StateProtocol.FromBytes(result.Buffer);
                    var robeatsDevice = new RobeatsDevice
                    {
                        Id = stateProtocol.DeviceId,
                        Name = stateProtocol.DeviceName,
                        EndPoint = client.Client.RemoteEndPoint,
                        StateProtocol = stateProtocol

                    };
                    OnDiscoveryReply(new DeviceDiscoveryEventArgs {RobeatsDevice = robeatsDevice});

            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
    }

【讨论】:

  • (顺便说一下,为了清楚起见,我建议使用Receive() 而不是ReceiveAsync()...)
  • 为什么?因为等待?
  • 这也给了我一个System.Net.Sockets.SocketException (0x80004005): A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied
  • 我假设后者是从您的OnDiscoveryReply() 下抛出的,您没有显示。如错误消息所示,您必须在发送数据时指定地址 - 再次因为 UDP 是无连接的。我们只在此处看到您收到的信息。
  • Receive() 用于阻塞模式套接字(您正在使用的默认值)。 ReceiveAsync() 用于一般情况。它会按原样工作,但总是和 Receive() 一样,返回 false。
猜你喜欢
  • 2016-10-07
  • 1970-01-01
  • 2014-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-13
相关资源
最近更新 更多