背景

ONVIF设备搜索和发现,分为Ad hoc模式和Managed模式两种。本文主要讲述Ad hoc模式中如何使用广播搜索和发现设备。

文章发表的顺序可能有点乱,麻烦根据《基于ONVIF协议的摄像机监控管理平台(1)概述》里面的文章目录进行阅读,抱歉了


一、广播的缺点

广播是很容易导致广播风暴的,一般情况下可以选择组播的一般不选择广播。
但是广播也是ONVIF里面支持的。
上一篇文章,讲述了怎么使用组播进行设备检索。有需要的可以去看一下。
《基于ONVIF协议的摄像机监控管理平台(4)使用组播搜索发现设备WS-Discovery》



二、广播怎么使用

广播方式其实和组播的方式差不多。唯一不同的,就是发送出去的信息是广播信息。但是后续的内容基本上差不多。

  1. 这里用的是UdpClient,c#中还有其它的方式发送组播udp的,但是思路基本差不多
  2. 创建socket
  3. 绑定端口和本地地址
  4. 允许端口复用
  5. 监听端口信息(先监听然后再发广播)
  6. 发送组播信息
  7. 接收信息(既可以同步也可以异步,根据实际情况来选择吧)
  8. 代码可以参考一下下面的。
    UdpClient udpClient = new UdpClient(AddressFamily.InterNetwork);
    IPEndPoint iep = new IPEndPoint(IPAddress.Broadcast, 3702);
    udpClient.Client.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReuseAddress, true);
    udpClient.Client.Bind(new IPEndPoint(IPAddress.Parse("192.168.110.55"), 9876));
    udpClient.BeginReceive(OnReceiveSink, new object[] { udpClient, new  IPEndPoint(IPAddress.Any, ((IPEndPoint)udpClient.Client.LocalEndPoint).Port) });
    while (true)
    {
    byte[] bytes0 = Encoding.ASCII.GetBytes("<?xml version=\"1.0\" encoding=\"utf - 8\"?><Envelope xmlns:tds=\"http://www.onvif.org/ver10/device/wsdl\" xmlns=\"http://www.w3.org/2003/05/soap-envelope\"><Header><wsa:MessageID xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">uuid:b2d3105d-34a2-40cd-b23c-dd70f34b44ca</wsa:MessageID><wsa:To xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">urn:schemas-xmlsoap-org:ws:2005:04:discovery</wsa:To><wsa:Action xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</wsa:Action></Header><Body><Probe xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\"><Types>tds:Device</Types><Scopes /></Probe></Body></Envelope>");
    
    byte[] bytes1 = Encoding.ASCII.GetBytes("<?xml version=\"1.0\" encoding=\"utf - 8\"?><Envelope xmlns:dn=\"http://www.onvif.org/ver10/network/wsdl\" xmlns=\"http://www.w3.org/2003/05/soap-envelope\"><Header><wsa:MessageID xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">uuid:de75a192-aadd-4caf-ab8f-99a3f08939d1</wsa:MessageID><wsa:To xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">urn:schemas-xmlsoap-org:ws:2005:04:discovery</wsa:To><wsa:Action xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</wsa:Action></Header><Body><Probe xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\"><Types>dn:NetworkVideoTransmitter</Types><Scopes /></Probe></Body></Envelope>");
    
    try
    {
    udpClient.Send(bytes0, bytes0.Length, multicastEndPoint);
    udpClient.Send(bytes1, bytes1.Length, multicastEndPoint);
    }
    catch { }
    Thread.Sleep(10000);
    }
    

三、接收信息

接收信息的函数,其实就和组播的时候用的几乎一样。



  1. 摄像机在收到广播信息之后,会往刚才发送探测信息的IP地址和端口发送一个udp包。
  2. 如果需要监控这一系列的网络交互过程,可以用wireshark抓包监控。
  3. 我这里用的异步,需要同步接收的请修改一下。
  4. 代码可以参照下面的。
        private void OnReceiveSink(IAsyncResult result)
        {
            try
            {
                IPEndPoint ep = null;
                var args = (object[])result.AsyncState;
                var session = (UdpClient)args[0];
                var local = (IPEndPoint)args[1];
                byte[] buffer = session.EndReceive(result, ref ep);
                Console.WriteLine("Message received from " + ep + " to " + local);
                Console.WriteLine(Encoding.ASCII.GetString(buffer));
                session.BeginReceive(OnReceiveSink, args);
            }
            catch { }
        }
    

后记

有任何的疑问或者想法,或者对本文有质疑或者补充的话,欢迎在留言区评论,期待你的分享!


同时,也欢迎关注本人微信公众号或者打赏一下这篇文章。





http://xzh.i3geek.com

爱唠叨的老鱼

爱唠叨的老鱼

技术经理,个人站长,创业者

0 条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据