1

Windows 8 メトロ プログラムで 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 要求をキャプチャすることさえできない場合があります。

ときどき機能するため、これは非同期の問題ではないと思います。私を助けてください !ありがとう!

4

3 に答える 3

2

UDP マルチキャスト要求を送信するローカル ネットワーク アダプターに割り当てられた IP アドレスに、ローカル エンドポイントをバインドしてみてください。

パケット スニファで発信 UDP パケットが表示されないという事実は、キャプチャしているネットワーク インターフェイスとは異なるネットワーク インターフェイスで要求が送信されていると思わせます。複数のネットワーク インターフェイス (イーサネットや WLAN など) があると仮定します。マルチキャストを扱うときは、接続されているすべてのネットワークに物理的に到達するために、要求がすべてのネットワーク インターフェイスで送信されることを確認する必要があります。

ローカル IP アドレスのクエリも参照してください。

于 2013-01-04T13:51:20.067 に答える
0

SocketOptionName.ReuseAddressソケットに力を入れる必要があると思います。私がそう思う理由を説明することはできません。ローカル エンドポイントにポート 1900 を使用しようとする @Joern と同じ間違いをしていないことは明らかです。しかし、それは私が見ることができる唯一の違いであり、彼の状況はまだ当てはまります。Windows ボックスで別の UPnP コントロール ポイントが既に実行されている可能性が非常に高いです。Windows 管理ツールで UPnP サービスを無効にして、コードがより確実に実行されるかどうかを確認してください。

または、@ Joern の方法で確立する UDP ソケットを書き直してみてください。私は C# の第一人者ではありませんが、特定の API を使用して同じことを複数の異なる方法で実行できる場合は、常に疑わしいものです。

于 2013-01-04T13:23:36.663 に答える