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 11运行Android应用得到保障,亚马逊应用商店将支持AAB