【问题标题】:SSDP discovery in Windows 8 Metro not reliableWindows 8 Metro 中的 SSDP 发现不可靠
【发布时间】:2012-12-31 09:25:48
【问题描述】:

我在 Windows 8 Metro 程序中实现 SSDP 发现时遇到问题。下面是代码:

public async Task SearchForDevices()
    {
        var socket = new DatagramSocket();
        socket.MessageReceived += async (sender, args) =>
                                            {
                                                Debug.WriteLine("Received data" + DateTime.Now);
                                                DataReader reader = args.GetDataReader();

                                                uint count = reader.UnconsumedBufferLength;
                                                string data = reader.ReadString(count);
                                                Debug.WriteLine(data);
                                                var response = new Dictionary<string, string>();
                                                foreach (
                                                    string x in
                                                        data.Split(new[] {"\r\n", "\n"}, StringSplitOptions.None))
                                                {
                                                    if (x.Contains(":"))
                                                    {
                                                        string[] strings = x.Split(':');
                                                        response.Add(strings[0].ToLower(), x.Remove(0, strings[0].Length + 1));
                                                    }
                                                }

                                                Device device = await GetXml(response);
                                                Debug.WriteLine("Device found");
                                                if (DeviceFound != null)
                                                    DeviceFound(this, new DeviceFoundEventArgs(device));
                                            };
        await socket.BindEndpointAsync(null, "");
        HostName hostName = new HostName("239.255.255.250");
        socket.JoinMulticastGroup(hostName);

        string message = "M-SEARCH * HTTP/1.1\r\n" +
                               "HOST: " + hostName.DisplayName + ":1900\r\n" +
                               "ST: upnp:rootdevice\r\n" +
                               "MAN: \"ssdp:discover\"\r\n" +
                               "MX: 3\r\n\r\n";

        DateTime start = DateTime.Now;
        TimeSpan interval = new TimeSpan(0, 0, 30);
        Debug.WriteLine(start);
        IOutputStream stream = await socket.GetOutputStreamAsync(hostName, "1900");
        var writer = new DataWriter(stream) { UnicodeEncoding = UnicodeEncoding.Utf8 };
        writer.WriteString(message);
        await writer.StoreAsync();
        await Task.Delay(1500);
    }

这段代码根本不可靠。大约 50% 的时间它找不到连接的设备,而其他发现可以找到。但有时它会起作用。

即使我已经多次调用,我的网络嗅探器 (SmartSniff) 有时甚至无法捕获其 SSDP 请求。

我不认为这是一个异步问题,因为它偶尔会起作用。 请帮我 ! 谢谢!

【问题讨论】:

  • 我不确定您是否要将 hostName 传递给 GetOutputStreamAsync。这是一个多播套接字这一事实使这成为一个难题。但我认为,如果你甚至没有看到你的“消息”被你的数据包嗅探器击中,那么其他事情正在发生。

标签: c# windows microsoft-metro ssdp


【解决方案1】:

尝试将本地端点绑定到分配给您希望发送 UDP 多播请求的本地网络适配器的 IP 地址。

您没有使用数据包嗅探器看到传出的 UDP 数据包这一事实使我相信该请求是在与您捕获的网络接口不同的网络接口上发送的。我假设您有多个网络接口(例如以太网和 WLAN)。处理多播时,您必须确保您的请求在所有网络接口上发送,以物理到达所有连接的网络。

另见Query Local IP Address

【讨论】:

    【解决方案2】:

    我认为您将不得不在您的套接字上强制使用SocketOptionName.ReuseAddress。我无法解释为什么我这么认为,你显然没有犯与@Joern of trying to use port 1900 for the local endpoint 相同的错误。但这是我能看到的唯一区别,他的情况仍然适用:很可能另一个 UPnP 控制点已经在您的 Windows 机器上运行。尝试在 Windows 管理工具中禁用 UPnP 服务,看看您的代码运行是否更可靠。

    或者尝试重写以@Joern 的方式建立的UDP 套接字。我不是 C# 专家,但当某些 API 允许您以多种不同的方式做同样的事情时,我总是很怀疑。

    【讨论】:

    • 不 - 完全没有必要。在进行 M-SEARCH 时,任何短暂的本地端口就足够了,因此 ReuseAddress 什么都不做。
    【解决方案3】:

    如果我猜对了 await Task.Delay(1500); 意味着您允许任务在完成前运行 1.5 秒,那么您有一个有趣的问题原因。

    您会看到,M-SEARCH 中的“MX: 3”表示“随机延迟回复,最多 3 秒”。鉴于您只等待 1.5 秒,因此您会丢失大约 50% 的响应是有道理的;-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-19
      相关资源
      最近更新 更多