ssdp协议搜索GB28181设备

article/2025/10/1 2:41:52

1、http协议和ssdp协议

ssdp协议近似于http协议,事实上,和http协议相似得地方就是他得协议内容,当然,我们要去除他得端口和d类地址。

为什么我在给其他员工或者面试得时候要他人深入一些,理解一下http协议,是因为理解了http协议,掌握ssdp也就不远了,很多人可能会问:http协议有啥内容,无非就是get,post,put,delete 么,还能怎么样,我经常问他们一点:http协议怎么知道他结束了?

大部分面试者支支吾吾答不出来,就这么奇怪,有一部分人说socket.close(), socket 关闭是因为你知道结束了才关闭,不是因为关闭知道http协议结束。两个\r\n\r\n代表http协议内容部分结束,至于二进制,当然有content-length 字段去表述了。我们来看一下ssdp协议:

static const char* ssdp_search =
"M-SEARCH * HTTP/1.1"
"HOST: 239.255.255.250:1900"
"MAN: \"ssdp:discover\""
"MX: 5"
"ST: ssdp:all";

这代表了搜索所有设备,这样对否,能出结果否,在239.255.255.250 这种d类ip地址上,端口1900发出该字符串,应该收到很多设备发出得信息,例如摄像头信息,你一定会搜到,不过,这一段代码搜索不到?为什么?看正确得写法:

static const char* ssdp_search =
"M-SEARCH * HTTP/1.1\r\n"
"HOST: 239.255.255.250:1900\r\n"
"MAN: \"ssdp:discover\"\r\n"
"MX: 5\r\n"
"ST: ssdp:all\r\n\r\n";

虽然ssdp是udp协议,但是他依然需要\r\n来代表行结束,\r\n\r\n代表协议内容部分结束。这样,就会搜索到所有信息,当然了,我们可以使用过滤,只搜索部分协议,比如就是摄像头,其他设备忽略。

2、发现谁在发现

除了搜索设备,我们还需要知道谁往我们得服务地址发送了搜索地址得需求,因为我们是一个设备,其他在gb28181 服务中,我们需要知道sip 网守和网关得设备,可能有多个这种设备,我们则需要知道谁正需要发现设备,我们写出以下代码:

#include <stdio.h>  
#include <winsock2.h>  
#include <ws2tcpip.h>  
#pragma comment(lib, "ws2_32.lib")int main_2()
{int iRet = 0;WSADATA wsaData;WSAStartup(MAKEWORD(2, 2), &wsaData);SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);sockaddr_in addr;addr.sin_family = AF_INET;//addr.sin_addr.S_un.S_addr = INADDR_ANY;addr.sin_addr.S_un.S_addr = inet_addr("192.168.0.129");addr.sin_port = htons(1900);bool bOptval = true;iRet = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&bOptval, sizeof(bOptval));if (iRet != 0) {printf("setsockopt fail:%d", WSAGetLastError());return -1;}iRet = ::bind(sock, (sockaddr*)&addr, sizeof(addr));if (iRet != 0) {printf("bind fail:%d", WSAGetLastError());return -1;}printf("socket:%d bind success\n", sock);// 加入组播  ip_mreq multiCast;//multiCast.imr_interface.S_un.S_addr = INADDR_ANY;multiCast.imr_interface.S_un.S_addr = inet_addr("192.168.0.129");multiCast.imr_multiaddr.S_un.S_addr = inet_addr("239.255.255.250");iRet = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&multiCast, sizeof(multiCast));if (iRet != 0) {printf("setsockopt fail:%d", WSAGetLastError());return -1;}printf("udp group start\n");int len = sizeof(sockaddr);char strRecv[1500] = { 0 };while (true){memset(strRecv, 0, sizeof(strRecv));iRet = recvfrom(sock, strRecv, sizeof(strRecv) - 1, 0, (sockaddr*)&addr, &len);if (iRet <= 0) {printf("recvfrom fail:%d", WSAGetLastError());return -1;}printf("recv data:%s\n", strRecv);}closesocket(sock);WSACleanup();return 0;
}

以上代码是windows示例,也可以用asio来制作,都一样。
在这里插入图片描述
可以看出有很多设备正在发ssdp协议,这样,找到自己感兴趣得ssdp设备,给他回信息就行。

3、标明我是谁

ssdp 简单服务发现协议最本质得关键还是在于服务得发现,反过来,不就是让对方发现我是谁,

static const char* ssdp_resinfo =
"HTTP/1.1 200 OK\r\n"
"CACHE-CONTROL:max-age=seconds\r\n"
"DATE:2022-07-09\r\n"
"EXT:\r\n"
"LOCATION: URL for UPnP description for root device\r\n"
"SERVER : OS / Version UPNP / 1.0 product / version\r\n"
"ST:search target\r\n"
"USN:advertisement UUID\r\n\r\n";

以下是摄像头返回得信息

HTTP/1.1 200 OK
CACHE-CONTROL: max-age=3600
DATE: Tue, 02 Aug 2022 14:44:45 GMT
EXT:
LOCATION: http://192.168.0.64:49152/upnpdevicedesc.xml
SERVER: Linux/4.9.37, UPnP/1.0, Portable SDK for UPnP devices/1.6.21
ST: urn:schemas-upnp-org:service:EmbeddedNetDeviceControl:1
USN: uuid:Upnp-iDS-ECD8012-M/E-1_0-F84224570::urn:schemas-upnp-org:service:EmbeddedNetDeviceControl:1

使用http协议解析以后,在获取LOCATION 地址,使用httpclient 访问地址,返回如下xml内容

<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<device>
<deviceType>urn:schemas-upnp-org:device:DigitalSecurityCamera:1</deviceType>
<friendlyName>HIKVISION iDS-ECD8012-M/E - F84224570</friendlyName>
<manufacturer>HIKVISION</manufacturer>
<manufacturerURL>http://www.hikvision.com</manufacturerURL>
<modelDescription>IP Camera</modelDescription>
<modelName>HIKVISION iDS-ECD8012-M/E</modelName>
<modelNumber>iDS-ECD8012-M/E</modelNumber>
<modelURL>http://www.hikvision.com</modelURL>
<serialNumber>F84224570</serialNumber>
<UDN>uuid:Upnp-iDS-ECD8012-M/E-1_0-F84224570</UDN>
<serviceList>
<service>
<serviceType>urn:schemas-upnp-org:service:EmbeddedNetDeviceControl:1</serviceType>
<serviceId>urn:upnp-org:serviceId:EmbeddedNetDeviceControl</serviceId>
<controlURL>/</controlURL>
<eventSubURL>/</eventSubURL>
<SCPDURL>/</SCPDURL>
</service>
</serviceList>
<presentationURL>http://192.168.0.64:80</presentationURL>
</device>
</root>

从中可以发现很多信息
那么现在我们得GB28181 服务有sip 服务,网关服务,中心节点服务,存储服务,推理服务,我们就必须标明自己得设备,并且写好XML文件,让对方获取,我们当然不必墨守成规,可以改成其他形式得文件,不过要考虑兼容性。

封装测试

在ssdp协议封装过程中,最为重要得一定是这个注意点,就是本机IP和主播地址IP,我们必须设置两个地址,在windows里面和linux下表现不同,必须要注意

int main(int argc, char* argv[])
{asio::io_context io_service;receiver r(io_service,asio::ip::address::from_string("192.168.0.129"),asio::ip::address::from_string("239.255.255.250"));thread t([&r,&io_service] {r.do_init("192.168.0.129");r.StartTimer();io_service.run();});while (1){Sleep(3000);}return 0;
}

http://chatgpt.dhexx.cn/article/sQmtShDL.shtml

相关文章

二叉树、红黑树

二叉树 遍历概念  所谓遍历(Traversal)是指沿着某条搜索路线&#xff0c;依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问题。  遍历是二叉树上最重要的运算之一&#xff0c;是二叉树上进行其它运算之基础。 遍历方案 1&#x…

图解红黑树及Java进行红黑二叉树遍历的方法

红黑树 红黑树是一种数据结构与算法课堂上常常提到但又不会细讲的树&#xff0c;也是技术面试中经常被问到的树&#xff0c;然而无论是书上还是网上的资料&#xff0c;通常都比较刻板难以理解&#xff0c;能不能一种比较直观的方式来理解红黑树呢&#xff1f;本文将以图形的方式…

算法 红黑树

红黑树 红黑树概述红黑树性质 红黑树的插入代码实现 红黑树概述 红黑树&#xff08;Red Black Tree&#xff09;是一种自平衡二叉查找树&#xff0c;是在计算机科学的中用到的一种数据结构&#xff0c;典型的用途是实现关联数组&#xff0c;红黑树和AVL树类似&#xff0c;都是…

【数据结构】--二叉树,红黑树

【数据结构】--二叉树&#xff0c;红黑树 &#x1f3c6;概念&#x1f34d;定义&#x1f34b; 术语&#x1f4dd;可视化网站 ☀️二叉树✨ 二叉搜索树&#x1f34d;定义&#x1f351;查找节点&#x1f34b;插入节点&#x1f345;遍历节点&#x1f355; 前序排序&#x1f9c0; 后…

红黑树的详细实现(C++)

红黑树概念(concept) 树型结构主要用于搜索&#xff0c;一直是科学领域的重要演算法&#xff0c;当中探讨了树可能遇到的问题&#xff1a;树的成长可能偏向于一边&#xff0c;也就是不平衡现象。 二叉树是常见且广泛使用的一种树&#xff0c;面临其可能退化成链表的潜藏缺点&…

二叉树——二叉查找树和红黑树

二叉树 二叉树&#xff0c;是一个非常重要的数据结构&#xff0c;在日常的开发中起着很重要的作用&#xff0c;它也衍生出来的各种高效的复杂的数据结构&#xff0c;为我们解决问题提供了高效的解决方案。 二叉树&#xff0c;它是由各个数据节点和左右链接构成的一种类似树的数…

Java——红黑树

概念 红黑树也是一种二叉搜索树&#xff0c;但是和avl树不同&#xff0c;它并不是依靠平衡因子来保证树的平衡的&#xff0c;而是通过颜色 红黑树每个节点中会存储颜色&#xff0c;分为红色和黑色&#xff0c;通过红黑树的限制条件&#xff0c;可以保证从根节点出发到叶子节点…

二叉树--红黑树

红黑树 定义 红黑树&#xff0c;顾名思义&#xff0c;就是树的节点只有红色和黑色两种状态&#xff0c;通过这两种状态的标识和规定颜色的使用&#xff0c;来使树达到相对平衡。为什么说相对平衡&#xff1f;因为在红黑树中&#xff0c;所有的条件限制只能保证&#xff0c;所…

二叉树之红黑树

红黑树 概述 为什么要有红黑树&#xff1f;&#xff1f;&#xff1f; 特点 红黑规则 如何在红黑树上添加节点&#xff1f; &#xff08;1&#xff09;我们不妨假设加入的节点都是黑色 &#xff08;2&#xff09;如果我们加入的节点都是红色 红黑树添加节点后如何保持红…

红黑二叉树

红黑树 红黑树是每个节点都带有颜色属性的二叉查找树&#xff0c;颜色或红色或黑色。在二叉查找树强制一般要求以外&#xff0c;对于任何有效的红黑树我们增加了如下的额外要求: 节点是红色或黑色。 根节点是黑色。 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有…

红黑树-Java实现

目录 一、定义 二、插入 三、删除 四、全部代码 五、颜色效果 一、定义 红黑树是特殊的平衡二叉树&#xff0c;具有以下特性&#xff1a; 1、根节点的颜色是黑色 2、节点颜色要么是黑色、要么是红色 3、如果一个节点的颜色是红色&#xff0c;则它的子节点必须是黑色&…

红黑二叉树原理分析

1.引言 HashMap的基本结构是数组&#xff0c;链表和红黑树。以数组为基本形态&#xff0c;数组中的元素先以链表形式储存&#xff0c;当链表的长 度超过8时&#xff08;包含数组上的那个链表头&#xff09;就会将链表转换为红黑树&#xff0c;以加快修改和查询效率。当然除了H…

理解红黑树及代码实现

1.红黑树定义 红黑树是一颗 红-黑的平衡二叉树,它具有二叉树的所有特性,是一颗自平衡的排序二叉树.(树中任何节点值都大于左子节点的值&#xff0c;而且都小于右子节点的值),其检索效率高&#xff0c;它是一颗空树或它的左右两个子树高度差的绝对值不超过1&#xff0c;并且左右…

红黑二叉树的漫画讲解(轻松理解红黑二叉树原理)

———————————— 二叉查找树&#xff08;BST&#xff09;具备什么特性呢&#xff1f; 1.左子树上所有结点的值均小于或等于它的根结点的值。 2.右子树上所有结点的值均大于或等于它的根结点的值。 3.左、右子树也分别为二叉排序树。 下图中这棵树&#xff0c;就是…

Java的二叉树、红黑树、B+树

数组和链表是常用的数据结构&#xff0c;数组虽然查找快&#xff08;有序数组可以通过二分法查找&#xff09;&#xff0c;但是插入和删除是比较慢的&#xff1b;而链表&#xff0c;插入和删除很快&#xff08;只需要改变一些引用值&#xff09;&#xff0c;但是查找就很慢&…

二叉树与红黑树

二叉树的形成 二叉树是n(n>0)个结点的有限集合&#xff0c;该集合或者为空集&#xff08;称为空二叉树&#xff09;&#xff0c;或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树组成 二叉树特点 由二叉树定义以及图示分析得出二叉树有以下特点&#xff1…

红黑树(C++实现)

文章目录 红黑树的概念红黑树的性质红黑树结点的定义红黑树的插入红黑树的验证红黑树的查找红黑树的删除红黑树与AVL树的比较 红黑树的概念 红黑树是一种二叉搜索树&#xff0c;但在每个结点上增加了一个存储位用于表示结点的颜色&#xff0c;这个颜色可以是红色的&#xff0c;…

红黑二叉树详解及理论分析

发表于我的博客网站(prajna.top)&#xff1a; http://prajna.top/doc/2/175 什么是红-黑二叉树&#xff1f; 红-黑二叉树首先是一颗二叉树&#xff0c;它具有二叉树的所有性质&#xff0c;是一种平衡二叉树。普通二叉树在生成过程中&#xff0c;容易出现不平衡的现象&#xff…

二叉树到红黑树

二叉树查找树 又叫二叉排序树。二叉查找树或者是一棵空树&#xff0c;或者是一棵具有如下性质的二叉树&#xff1a; 对于任何一个结点X若它的左子树非空&#xff0c;则左子树上所有结点的值均小于等于X的值&#xff1b;若它的右子树非空&#xff0c;则右子树上所有结点的值均大…

详解c++---红黑二叉树的原理和实现

目录标题 什么是红黑二叉树树红黑树的性质红黑树的效率分析红黑树的准备工作红黑树的insert函数节点的调整情况一情况二情况三 转换的实现打印函数find函数检查函数 什么是红黑二叉树树 avl树是通过控制平衡因子来控制二叉搜索树的平衡&#xff0c;当某个节点的平衡因子等于2或…