Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Windows应用商店应用程序(.NET)上的SSDP(UDP)_C#_Udp_Multicast_Windows Store_Philips Hue - Fatal编程技术网

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

C# Windows应用商店应用程序(.NET)上的SSDP(UDP),c#,udp,multicast,windows-store,philips-hue,C#,Udp,Multicast,Windows Store,Philips Hue,我正在尝试使用C#为Windows应用商店应用程序实现一个基本的SSDP(UDP)广播/侦听器 我发现Windows.Networking.Sockets包含DatagramSocket类,这是我需要用于UDP网络的类 然而,我目前的尝试似乎执行得很好,但通过Wireshark没有结果,也没有从网络上的设备得到响应 以下是我当前正在使用的代码(并在RT模拟器中运行): 公共异步静态任务发现同步(TimeSpan超时) { 如果(超时) { var bpx=true;//此处为成功断点 }; va

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

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

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

以下是我当前正在使用的代码(并在RT模拟器中运行):

公共异步静态任务发现同步(TimeSpan超时)
{
如果(超时)
{
var bpx=true;//此处为成功断点
};
var multicastIP=新主机名(“239.255.255.250”);
等待socket.BindServiceNameAsync(“1900”);
socket.JoinMulticastGroup(multicastIP);
使用(var writer=newdatawriter(socket.OutputStream))
{
var请求=新的StringBuilder();
请求。附录行(“M-SEARCH*HTTP/1.1”);
request.AppendLine(“主机:239.255.255.250:1900”);
请求。追加行(“MAN:ssdp:discover”);
请求。附录行(“MX:5”);
请求。附录行(“ST:ssdp:all”);
writer.WriteString(request.ToString());
等待writer.FlushAsync();
}
如果(超时>时间跨度为零)
等待任务。延迟(超时);
如果(!bridgeWasFound)
break;//此处为故障检查断点
}
}
返回发现的桥梁;
}

关于我可能做得不正确有什么想法吗?我没有发现异常,我在清单中设置了正确的功能。我在
中断处的断点总是被击中,我使用了10秒的超时时间。

似乎我已经发现了问题

首先,我应该使用
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;
}
公共异步静态任务发现同步(TimeSpan超时)
{
如果(超时)
{
var reader=e.GetDataReader();
var byteslaining=reader.unsumedbufferlength;
var receivedString=reader.ReadString(字节剩余);
//TODO:检查现有桥,仅添加新桥以防止无限循环。
//TODO:创建新网桥并添加到列表中。
bridgeWasFound=true;
};
等待socket.BindEndpointAsync(null,string.Empty);
socket.JoinMulticastGroup(multicastIP);
while(true)
{
bridgeWasFound=false;
使用(var stream=await socket.GetOutputStreamAsync(multicastIP,“1900”))
使用(var writer=newdatawriter(流))
{
var请求=新的StringBuilder();
请求。附录行(“M-SEARCH*HTTP/1.1”);
request.AppendLine(“主机:239.255.255.250:1900”);
请求。追加行(“MAN:ssdp:discover”);
请求。附录行(“MX:3”);
请求。附录行(“ST:ssdp:all”);
writer.WriteString(request.ToString());
等待writer.StoreAsync();
如果(超时>时间跨度为零)
等待任务。延迟(超时);
如果(!bridgeWasFound)
打破
}
}
}
返回发现的桥梁;
}

根据规范:

HTTP扩展框架所需的MAN。与NTS和ST字段不同 值,则MAN header字段的字段值用双引号括起 引号;它定义扩展的作用域(命名空间)。必须为 “ssdp:发现”

然后你的代码

request.AppendLine("MAN: ssdp:discover");
一定是

request.AppendLine("MAN: \"ssdp:discover\"");
希望这有帮助

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