Windows 应用商店应用程序 (.NET) 上的 SSDP (UDP)

Posted

技术标签:

【中文标题】Windows 应用商店应用程序 (.NET) 上的 SSDP (UDP)【英文标题】:SSDP (UDP) on Windows Store applications (.NET) 【发布时间】:2012-12-26 13:09:49 【问题描述】:

我正在尝试使用 C#Windows Store 应用程序实现一个基本的 SSDP (UDP) 广播/侦听器em>。

我发现Windows.Networking.Sockets 包含DatagramSocket 类,这是我需要用于UDP 网络的。

但是,我目前的尝试似乎执行得很好,但通过 Wireshark 没有结果,也没有从网络上的设备得到响应。

这是我目前正在使用的代码(并通过 RT 模拟器运行):

public async static Task<IEnumerable<HueBridge>> DiscoverAsync(TimeSpan timeout)

  if (timeout <= TimeSpan.Zero)
    throw new ArgumentException("Timeout value must be greater than zero.", "timeout");

  var discoveredBridges = new List<HueBridge>();

  using (var socket = new DatagramSocket())
  
    while (true)
    
      var bridgeWasFound = false;

      socket.MessageReceived += (sender, e) =>
      
        var bpx = true; // breakpoint here for success
      ;

      var multicastIP = new HostName("239.255.255.250");
      await socket.BindServiceNameAsync("1900");
      socket.JoinMulticastGroup(multicastIP);

      using (var writer = new DataWriter(socket.OutputStream))
      
        var request = new StringBuilder();
        request.AppendLine("M-SEARCH * HTTP/1.1");
        request.AppendLine("HOST: 239.255.255.250:1900");
        request.AppendLine("MAN: ssdp:discover");
        request.AppendLine("MX: 5");
        request.AppendLine("ST: ssdp:all");

        writer.WriteString(request.ToString());
        await writer.FlushAsync();
      

      if (timeout > TimeSpan.Zero)
        await Task.Delay(timeout);

      if (!bridgeWasFound)
        break; // breakpoint here for failure check
    
  

  return discoveredBridges;

关于我可能做错了什么有什么想法吗?我没有遇到异常,并且我在清单中设置了正确的 Capabilities。我在break 处的断点总是被命中,我使用的超时时间为 10 秒。

【问题讨论】:

【参考方案1】:

看来我找到了问题。

首先,我应该使用socket.BindEndpointAsync(null, string.Empty) 而不是socket.BindServiceNameAsync("1900"),这样可以正确监听广播数据包。

其次,writer.FlushAsync() 不写入套接字;但是,writer.StoreAsync() 可以。

这是最终结果,它确实(几乎)完美地工作:

public async static Task<IEnumerable<HueBridge>> DiscoverAsync(TimeSpan timeout)

  if (timeout <= TimeSpan.Zero)
    throw new ArgumentException("Timeout value must be greater than zero.", "timeout");

  var discoveredBridges = new List<HueBridge>();
  var multicastIP = new HostName("239.255.255.250");
  var bridgeWasFound = false;

  using (var socket = new DatagramSocket())
  
    socket.MessageReceived += (sender, e) =>
    
      var reader = e.GetDataReader();
      var bytesRemaining = reader.UnconsumedBufferLength;
      var receivedString = reader.ReadString(bytesRemaining);

      // TODO: Check for existing bridges, only add new ones to prevent infinite loop.
      // TODO: Create new bridge and add to the list. 

      bridgeWasFound = true;
    ;

    await socket.BindEndpointAsync(null, string.Empty);
    socket.JoinMulticastGroup(multicastIP);

    while (true)
    
      bridgeWasFound = false;

      using (var stream = await socket.GetOutputStreamAsync(multicastIP, "1900"))
      using (var writer = new DataWriter(stream))
      
        var request = new StringBuilder();
        request.AppendLine("M-SEARCH * HTTP/1.1");
        request.AppendLine("HOST: 239.255.255.250:1900");
        request.AppendLine("MAN: ssdp:discover");
        request.AppendLine("MX: 3");
        request.AppendLine("ST: ssdp:all");

        writer.WriteString(request.ToString());
        await writer.StoreAsync();

        if (timeout > TimeSpan.Zero)
          await Task.Delay(timeout);

        if (!bridgeWasFound)
          break;
      
    
  

  return discoveredBridges;

【讨论】:

【参考方案2】:

根据规格:

HTTP 扩展框架需要 MAN。不同于 NTS 和 ST 字段 values,MAN头字段的字段值用double括起来 引号;它定义了扩展的范围(命名空间)。一定是 “ssdp:发现”。

然后是你的代码

request.AppendLine("MAN: ssdp:discover");

必须是

request.AppendLine("MAN: \"ssdp:discover\"");

希望对您有所帮助。

【讨论】:

以上是关于Windows 应用商店应用程序 (.NET) 上的 SSDP (UDP)的主要内容,如果未能解决你的问题,请参考以下文章

使用 protobuf-net 为 Windows 商店应用程序序列化私有成员

如何在 C# 中捕获 Windows 应用商店应用程序的窗口内容

从桌面运行 Windows 应用商店应用程序

Windows 11运行Android应用得到保障,亚马逊应用商店将支持AAB

Windows 应用商店应用程序 - 控制台应用程序 IPC 命名管道连接

如何在 Windows 上使用快速通道将 React Native iOS 应用程序部署到应用商店?