gb28181协议详解_GB28181收费吗

gb28181协议详解_GB28181收费吗ssdp协议近似于http协议,事实上,和http协议相似得地方就是他得协议内容,当然,我们要去除他得端口和d类地址。为什么我在给其他员工或者面试得时候要他人深入一些,理解一下http协议,是因为理解了http协议,掌握ssdp也就不远了,很多人可能会问http协议有啥内容,无非就是get,post,put,delete么,还能怎么样,我经常问他们一点http协议怎么知道他结束了?虽然ssdp是udp协议,但是他依然需要\r\n来代表行结束,\r\n\r\n代表协议内容部分结束。……

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

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;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/183326.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 一篇文章带你深入理解 Java 中的Class.getClassLoader[通俗易懂]

    一篇文章带你深入理解 Java 中的Class.getClassLoader[通俗易懂]文章目录一、ClassLoader的作用二、ClassLoader层次结构三、Class加载时调用类加载器的顺序一、ClassLoader的作用我们都知道java程序写好以后是以.java(文本文件)的文件存在磁盘上,然后,我们通过(bin/javac.exe)编译命令把.java文件编译成.class文件(字节码文件),并存在磁盘上。但是程序要运行,首先一定要把.class文件加载…

  • 协方差矩阵计算实例「建议收藏」

    协方差矩阵计算实例「建议收藏」协方差矩阵计算实例突然发现给一组数据去实际计算对应得协方差矩阵,让人有点懵,并未找到太清楚的讲解,这里举一个实例记录一下。1、别把样本数和维度数搞混了具体进行计算容易懵的原因就是很容易把样本数和维度数搞混,维度数n,那么得到的协方差矩阵就是n*n的,和样本数没啥关系。这里还是要明确一下,维度数即是每条样本中的变量数,协方差即是对不同变量的同向程度进行的衡量,下面举个例子来具体说明一下。2、实例说明一下样本:一共4条,2维的这里再强调一下,每条样本都是2维的,即每条样本都包含对两个变量

  • 探索Android中的Parcel机制(上)

    探索Android中的Parcel机制(上)

    2021年12月10日
  • 重新认识Attributes.add

    重新认识Attributes.add昨天自己学习别人的编码,发现了控件ID.Attributes.add("","");用法,于是自己查来看,中间闹了不少的笑话;首先自己就搜错了对象,C#里有

  • 推荐一个好的Redis GUI 客户端工具

    推荐一个好的Redis GUI 客户端工具

  • qmake:配置qmake

    qmake:配置qmake一、属性qmake有一个持久化配置系统,它允许在qmake中设置一次属性,并在每次调用qmake时查询它。可以在qmake中设置一个属性:qmake-setPROPERTYVALUE您可以从qmake检索此信息,如下所示:qmake-queryPROPERTYqmake-query//列出内置属性以下是内置属性:QMAKE_SPEC:在主机构建期间解析并存储在QMAKESPEC变量中的主机mkspec的短名称

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号