Linux - 应用层HTTPS、传输层TCP/IP模型中典型协议解析

目录

  • 应用层:
    • 自定制协议
      • 实例
    • HTTP协议
      • 首行
      • 头部
      • 空行
      • 正文
      • http服务器的搭建
    • HTTPS协议
  • 传输层
    • UDP协议
    • TCP协议

应用层:

应用层负责应用程序之间的沟通—程序员自己定义数据的组织格式
应用层协议:如何将多个数据对象组织成为一个二进制数据串进行传输
需要考虑的要素:传输性能,解析性能,调试便捷性

序列化:将数据对象按照指定协议进行组织成实现持久化存储或者网络通信传输的二进制数据串的过程
反序列化:按照指定协议,将二进制数据串解析得到各个数据对象的过程
序列化方式:结构体二进制序列化、json序列化、protobuf序列化

自定制协议

自定制协议:程序员自己定制数据格式

实例

网络版计算器:
客户端将两个数字,以及运算符,传输给服务端
服务端对数据进行运算,将结果返回给客户端
具体结构在上一篇博客套接字部分,这里只是讲自定制协议

1.首先在tcpsocket头文件里面自定义数据格式

struct data_t
{int num1;int num2;char op;
};

2.在tcp_cli客户端收发数据部分进行发送与接收

//4.收发数据struct data_t tmp;tmp.num1 = 11;tmp.num2 = 22;tmp.op = '+';//方法一:调用自定义函数//std::string buf;//buf.resize(sizeof(struct data_t));//memcpy(&buf[0], &tmp, sizeof(struct data_t));//CHECK_RET(cli_sock.Send(buf));//buf.clear();//CHECK_RET(cli_sock.Recv(&buf));//std::cout << *(int*)buf.c_str() << std::endl;//方法二:int fd = cli_sock.GetFd();send(fd, (void*)&tmp, sizeof(struct data_t), 0);int result;recv(fd, &result, sizeof(int), 0);std::cout << result << std::endl;

3.在tcp_srv服务端收发数据部分进行接收与发送

//5.收发数据    --使用获取的新建套接字进行通信int fd = clisock.GetFd();struct data_t tmp;recv(fd, &tmp, sizeof(struct data_t), 0);int result;if(tmp.op == '+'){result = tmp.num1 + tmp.num2;}else{result = 0;}send(fd, &result, sizeof(int), 0);

HTTP协议

HTTP协议:超文本传输协议
http协议格式:http的协议实现,http协议的数据结构
首行:请求行,响应行(对于请求与相应的简单关键描述)
头部:对于请求或者响应或者正文的一些关键描述
由一个个键值对组成key:val, 每个键值对以\r\n结尾
空行:\r\n,间隔头部与正文;\r\n\r\n – 头部结尾
正文:客户端提交给服务端,或者服务端响应给客户端的数据

首行

-请求行:请求方法,URL(URI),协议版本\r\n

请求方法
GET:从服务器获取实体资源,请求没有正文,但是也可以提交数据,但是提交的数据没有在正文中而是在URL中
1.get提交数据不安全;2.URL长度有限制
HEAD:功能与GET类似,但是不要正文实体
POST:向服务端提交数据,请求有正文,数据放在正文中

URL:网址–统一资源定位符–用于定位网络中某个主机上的某个资源
组成:协议名称://用户名:密码@域名:端口/资源路径?查询字符串
https://user:password@www.baidu.com:80/s?ie=utf-8&wd=ASCII
域名:服务器别名–最终访问服务器需要经过域名解析得到服务器IP
资源路径:这个路径是一个相对根目录
查询字符串:提交给服务器的数据,由一个个key=val形式键值对组成,键值对之间以&符号间隔
urlencode:编码-用户请求的资源路径,或者查询字符串中存在特殊字符,则有可能与url中的特殊字符冲突;将特殊字符每个字节转换为16进制数字字符,并前缀%
urldecode:解码-遇到%则认为紧随其后的两个字符进行了编码,将这两个字符转换为数字,第一个数字左移4位加上第二个数字

协议版本:0.9,1.0,1.1,2
0.9:最早期版本,只支持GET方法,并且协议还没有当前的规范,只支持超文本数据传输。
1.0:规范了http协议格式,并且新增支持GET,HEAD,POST请求方法支持各种多媒体资源传输,简单的缓存控制。
1.1:更多的是对1.0版本进行性能的优化,支持了更多请求方法以及特性(支持长连接,更加完善的缓存控制,分块传输…)
2.0:因为http协议的庞大冗余,因此2.0不是新增特性,而是重新定义http协议①使用二进制数据传输;②支持主动推送资源;③服务器进行长连接响应,不需要按序进行

Connection:用于控制长连接的打开关闭状态 keep-alive/close

-响应行:协议版本,响应状态码,状态码描述\r\n

响应状态码:直观向客户端反馈处理结果
1××:一些描述信息;101-协议切换状态码
2××:表示本次请求正确处理;200
3××:重定向-表示本次请求的资源移动到了新的链接处,并且原链接依然可用;301/302
4××:表示客户端错误;404
5××:表示服务器错误;500-服务器内部错误;502-代理服务器没有收到正确响应;504-超时
状态码描述:就是针对状态的文字描述

头部

头部:关于请求或者响应,或者正文的一些描述字段
组成:key:val\r\n key:val\r\n
典型头部字段
Connection:长短连接控制;keep-alive/close
Referer:记录本次请求的来源链接
Content-Type:用于表示正文的数据格式
Content-length:用于表示正文的长度–http解决粘包问题的关键字段
Location:用于指定重定向的新链接地址,与3××搭配使用
cookie与session:涉及的头部字段请求头Cookie,响应头Set-Cookie
http协议是一个无状态协议
1.一个客户端登陆之后,服务端验证登录,成功后,通过Set-Cookie字段设置cookie信息(用户信息,状态…)返回给客户端
2.客户端收到响应后,将Set-Cookie字段的cookie信息保存起来,下次请求服务器的时候从cookie文件中读取出cookie信息,通过Cookie字段发送给服务器。
cookie是一个维护http通信状态的技术–但是存在安全隐患。
解决方案:session
session是服务端针对每个客户端所建立的会话,当客户端登录成功后,创建会话,在会话中记录客户端用户信息以及状态…,通过Set-Cookie字段将session_id返回给客户端
session_id每次请求都会发生变化,并且用户的隐私信息一直保存在服务器防止泄露。
cookie与session的区别
cookie是维护http通信状态的技术,将关键信息保存在客户端,每次请求服务器时,读取出来发送给服务端(存在安全隐患)
session是解决cookie安全隐患的技术,将关键信息保存在服务器,将sessionid发送给客户端,作为cookie保存起来,解决了cookie泄密的风险。

空行

空行:\r\n
是与头部最后一个字段的结尾\r\n组成连续的\r\n\r\n作为特殊标志
作为http头部结尾的标志

正文

针对不同的传输所提交的数据或服务端响应的数据,以什么格式我们自己来定。

http服务器的搭建

http是一个应用层协议,只是应用程序如何沟通的一种数据格式约定,在传输层是基于tcp实现的 http客户端实际上就是一个tcp客户端;http服务器实际上就是一个tcp服务器,只不过http客户端与服务端的通信使用的是http协议来约定数据格式而已。
简单的http服务器的搭建:
1.搭建tcp服务端
2.获取新建连接
3.使用新建连接,等待接收数据(http协议的请求数据)
4.接收过程:先接受http头部,解析头部-Content-Length确定正文长度
5.接收指定长度的正文
6.根据请求方法以及资源路径确定客户端的请求目的
7.进行具体对应的业务处理
8.组织http协议格式的响应数据,对客户端进行回复
9.如果是短连接,则直接关闭套接字,如果是长连接,则继续等待接收数据


#include "tcpsocket.hpp"
#include<sstream>int main(int argc, char *argv[])
{//通过程序运行参数执行服务端要绑定的地址//./tcp_srv 192.168.2.2 9000if(argc != 3){printf("usage: ./tcp_src 10.106.200.199 9000\n");return -1;}std::string srvip = argv[1];uint16_t srvport = std::stoi(argv[2]);TcpSocket lst_sock;//监听套接字//1.创建套接字CHECK_RET(lst_sock.Socket());//2.绑定地址信息CHECK_RET(lst_sock.Bind(srvip, srvport));//3.开始监听CHECK_RET(lst_sock.Listen());while(1){       //4.获取新建连接TcpSocket clisock;std::string cliip;uint16_t cliport;bool ret = lst_sock.Accept(&clisock, &cliip, &cliport);if(ret == false){       continue;}
//------------------------------------------------------http服务端接收数据----------------------------------------------std::string buf;clisock.Recv(&buf);std::cout << "request:[" << buf << "]\n";std::string body = "<html><body><h1>Hello ysy</h1></body></html>";std::stringstream ss;//首行ss << "HTTP\1.1 200 OL\r\n";//头部ss << "Connection: close\r\n";ss << "Content-Length:" << body.size() << "\r\n";ss << "Content-Type: text/html\r\n";//空行ss << "\r\n";//正文ss << body;clisock.Send(ss.str());clisock.Close();
//------------------------------------------------------http服务端接收数据----------------------------------------------}//6.关闭套接字lst_sock.Close();return 0;
}

注意:http服务器编写完毕之后
云服务器:记得设置安全组策略,开启对应端口
虚拟机:记得关闭防火墙 sudo systemctl stop firewalld

//302重定向std::string buf;clisock.Recv(&buf);std::cout << "request:[" << buf << "]\n";std::string body = "<html><body><h1>Hello ysy</h1></body></html>";std::stringstream ss;//首行:302重定向ss << "HTTP\1.1 302 OL\r\n";//头部ss << "Connection: close\r\n";ss << "Content-Length:" << body.size() << "\r\n";ss << "Content-Type: text/html\r\n";//重定向ss << "Location: http://www.baidu.com\r\n";//空行ss << "\r\n";//正文ss << body;clisock.Send(ss.str());clisock.Close();

HTTPS协议

HTTPS协议:并不是一个新的协议,而是在HTTP协议基础上进行了一层加密
https协议就是基于ssl进行加密实现加密传输
HTTPS=HTTP+SSL
目的:实现数据的安全传输
安全传输:需要考虑两个问题
1.身份验证问题:防止伪装
2.数据加密问题:防止监听

身份验证实现
原理:使用第三方权威机构进行身份验证(CA证书)
CA认证:通信双方在通信前先到权威机构请求给自己颁发一个CA证书。CA证书(权威机构信息,自己的信息,…),通信两方建立连接后,在通信之前先将证书发送给对方,收到对方的证书后,查看这个权威机构是否是自己新人的权威机构,如果是,则到权威机构进行这个公司的身份验证。验证通过后进行通信,不通过可以自行选择是否添加信任。
身份验证通过,但是通信依然有可能被监听,存在风险,因此需要加密传输。
加密传输实现
①.对称加密:加解密使用相同的秘钥。
优点:加解密效率高
缺点:秘钥一旦被劫持则加密形同虚设
②.非对称加密:加密和解密使用不同的秘钥
思路:通信中,每一端在通信前都可以生成一对秘钥(公钥和私钥),在通信前,将公钥发送给对方,对方使用收到的公钥进行加密数据然后传输,自己收到数据后,使用私钥进行解密。
实现算法:RSA加密算法
优点:安全度更高
缺点:加解密效率低下
③.混合加密
通信双方,先使用非对称加密保护对称秘钥协商过程。对称秘钥协商完毕后,使用对称秘钥加密传输。

https加密流程:(将身份验证(CA认证)与加密传输(混合加密)合在一起使用)
1.通信双方生成一对秘钥,使用公钥信息到权威机构生成一个CA证书
2.通信建立连接后,数据传输前,将证书先传输给对方
3.双方收到对方的证书后,进行解析,得到机构信息以及公钥信息
4.对机构信息进行验证
5.身份验证通过后,使用公钥加密数据(随机数+对称加密算法列表),发送给对方
6.双方收到对方使用公钥加密的数据后,使用私钥进行解密
7.给对方也发送一个随机数+对称加密算法列表
8.通过双方的随机数与算法列表生成一个对称秘钥
9.使用这个协商的对称秘钥加密通信

传输层

应用层协议目的是了解指定协议的实现便于我们以后使用
传输层:负责应用程序之间的数据传输–TCP/UDP
了解协议的实现,体会协议的特性,理解对于上层程序编程的影响

UDP协议

UDP协议格式
在这里插入图片描述
16位源端-对端端口:用于描述识别通信两端进程
16位数据报(UDP)长度:能够存储最大数字65535–udp报文总大小最大不能超过64k
16位校验和:采用二进制反码求和算法–校验接收方接收到的数据与发送方发送的数据是否一致。
协议特性
无连接:通信时不需要建立连接,只要知道对方地址就可以直接发送数据
不可靠:不保证数据安全、有序到达对端。
面向数据报:无连接的,不可靠的,无序的,有最大长度限制的传输方式
1.ucp传输时,sendto发送的数据会被发送到发送缓冲区中,而udp协议并不会等待,而是直接对数据封装头部,进行发送
2.udp传输时,收到的数据会被放到接收缓冲区中,而udp保证数据是整条交付,不会出现半条或多条交付。

编程影响
1.不保证安全到达:需要会在应用层使用tcp所使用的一些机制实现
2.不保证有序到达:需要在应用层进行包序管理
3.udp报文有最大长度限制:报文最大长度小于64k,因此发送大块数据的时候,需要在应用层进行数据分包进行发送
4.udp实现的是整条交付:因此接收方revcfrom所给予的buf(定义的缓冲区)足够大,能够一次性取出一条数据。

TCP协议

tcp协议格式:
在这里插入图片描述
16位源端-对端端口:描述识别两端
32位序号-确认号:进行包序管理
4位头部长度:以4字节为单位,表示tcp报头最大有60字节,最小20字节
6位保留
6位标志位
URG:紧急指针是否有效;
ACK:表示响应;
PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走;
RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段;
SYN:请求建立连接;我们把携带SYN标识的称为同步报文段;
FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段;
16位窗口大小:实现华东窗口机制
16位校验和:校验接收的数据与发送的数据是否一致
16位紧急指针:标识哪部分数据是紧急数据

协议特性:面向连接,可靠传输,面向字节流
面向连接:连接管理+状态管理
连接管理:
三次握手连接建立在这里插入图片描述> 四次挥手断开连接
在这里插入图片描述
问题
1.为什么握手是三次,而挥手是四次?
握手:tcp是一个全双工通信,两端都必须确认对方是否具有数据收发的能力。两次不安全,四次没必要。
挥手:fin包只能表示对方不再发送数据了,不代表对方不再接收数据,因此有可能被动关闭方还会继续发送数据,因此这种情况下就不能直接发送fin包,而是等待上层用户不在发送数据了,调用close或者shutdown才会发送fin包。因此被动关闭方的ack和fin并不是一起发送的。
2.tcp三次握手失败了,两端是如何处理的?
服务端回复ack+syn后,如果超时得不到ack回复,则会发送rst重置连接报文,然后释放新建套接字。
3.TIME_WAIT有什么用?
TIME_WAIT是主动关闭方在断开连接过程中进行最后一次ack回复后进入的状态。如果主动关闭方回复最后一次ack后直接释放资源,就有可能在新的客户端中使用原来的这个地址信息,在上次ack丢失的情况下收到重传的fin对新连接造成影响。TIME_WAIT更多的是为了保护客户端启动不会使用刚关闭的套接字地址信息,进而不会受到上个套接字的通信遗留问题影响。
详细说明:如果被动关闭方没有收到最后一次回复,则会重传fin;假设没有TIME_WAIT,主动关闭方最后一次恢复后直接释放资源。这时候如果客户端重新启动了一个套接字使用的刚好是之前的地址信息,这个套接字就有可能收到重传的这个fin。被动关闭方一致等待最后一个ack,但是这时候如果新的客户端启动发送syn,则与状态对应不上。
TIME_WAIT等待2个MSL时间之后,释放资源,等待两个msl是为了保证能够对重传的fin进行处理,以及保证本次通信的所有数据都消失在网络中不会对新的连接造成影响。
4.一台主机上出现了大量的TIME_WAIT是什么原因?如何解决?
TIME_WAIT是套接字主动关闭连接,最终进入的状态,因此一台主机出现大量TIME_WAIT意味着大量的主动关闭了套接字。
解决方法:
①.减少TIME_WAIT等待时间
②.使用套接字选项:地址复用
int setsockopt(int fd, int level, int optname, void* optval, int optlen);
level:SOL_SOCKET;optname:SO_REUSEADDR – 地址复用
5.一台主机上出现了大量的CLOSE_WAIT是什么原因?如何解决?
close_wait是被动关闭方,在收到fin包进行ack回复之后进入的状态。这个状态是等待上层用户层调用close/shutdown(wr)后发送fin包的一个状态。
如果主机上出现了大量的close_wait的连接,那么意味着可能在代码中没有关闭套接字。

TCP连接保活机制
通信两端在长时间没有数据通信的情况下,服务端会每隔一段时间向客户端发送一个保活探测数据包(要求对方进行回复),若连续多次没有收到回复,则认为连接已经断开。
默认7200s,每隔75s,9次无回复则断开
这些数值可以通过设置套接字选项进行设置。
连接断开对于程序的影响:recv返回0,send会触发SIGPIPE异常

可靠传输:保证数据有序,安全到达对端
1.面向连接
2.协议字段中的序号与确认序号,进行包序管理,实现有序传输。
3.确认应答机制:接收方针对收到的每一条数据进行确认回复
4.超时重传机制:发送数据等待超时时无确认回复后,认为数据丢失进行重传。
5.协议字段的校验和字段:校验数据一致性,不一致则丢弃,发送重传请求
6.避免丢包:
①.发送方发送数据过快,过多,导致接收方接收缓冲区满溢导致丢包
解决方案:滑动窗口机制–进行流量控制
每一方都会有一个:接收窗口,发送窗口
发送窗口:后沿:发送起始序号;前沿:结束发送位置。前沿减后沿不能大于对方的窗口大小
接收窗口:后沿:起始接收序号;前沿:结束接受位置。前沿减后沿不能大于剩余空间大小
停等协议:收到确认回复后才会发送下一条
回退n步协议:从丢失的数据开始进行重新传输
选择重传协议:哪条丢了就重传哪条
②.传输过程中,网络状态突然不好,导致大量丢包重传
解决方案:拥塞机制 – 以慢启动快增长的形式进行传输
实现原理:发送方维护一个拥塞窗口,用于限制当前所能发送的数据大小,而这个拥塞窗口以指数层级增长,实现网络探测,防止传输过程中网络状态突然变差继续大量发送导致的大量丢包。
7.性能的提升:避免无谓的一些性能损失
确认序号:是告诉发送方确认序号之前的所有数据都已经接收成功,避免因为中间的某个确认回复丢失而导致的重传。
快速重传机制:接收方在接收数据时,先接收到了后发的数据,则认为前边的数据有可能丢失了,则连续间隔发送三条前边数据的重传请求(确认序号为丢失的数据起始序号),发送方收到连续三条重传请求,主要目的是为了减少超时等待时间。三条重传请求是为了防止延迟到达的情况。
延迟应答机制:接收方收到数据后,延迟确认回复
接收方接收数据后如果立即进行回复,大概率窗口大小都会变小,延迟应答是为了在延迟期间上层可能将数据取出,尽量保证窗口大小,保证传输吞吐量。
捎带应答机制:将确认回复的信息,放到即将要发送的数据报头中,捎带一块传输给对方,尽可能减少纯报头的确认回复(一个报头至少20字节)

TCP如何实现可靠传输
1.可靠传输:面向连接,包序管理,确认应答,超时重传,校验和
2.避免丢包:滑动窗口,拥塞机制
3.提高性能:延迟应答,捎带应答,延迟发送
UDP如何实现可靠传输
在应用层用过tcp实现可靠传输的机制来实现

面向字节流:基于连接,可靠的,有序的,双向的一种字节流(以字节为单位)
TCP要发送的数据都会被放到发送缓冲区中,通信时tcp会从缓冲去中取出合适大小的数据(不大于mss大小),封装头部进行发送。
好处:传输比较灵活
坏处:会产生粘包问题 – 将多条数据当做一条进行处理-无法分辨数据边界
本质原因:tcp并不维护数据边界
解决方案:则需要程序员在应用层进行数据边界管理–区分数据边界
具体技术:特殊字符,数据定长,应用层头部加上数据长度字段
UDP不存在粘包问题。数据整条交付

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/762349.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ES集群部署指引

文章目录 引言I 清除last_run_metadata_path数据。II 配置IP2.1 CentOS系统的IP参数2.2 shell脚本-静态网络配置III 公司工作电脑的IP多号段配置3.1 Mac电脑3.2 windows系统see alsomac Rootlees 内核保护措施引言 申请两台Linux机器,存储1年的航迹数据,需要4T的存储空间。 E…

【算法刷题 | 二叉树 03】3.22 二叉树的层序遍历02(5题:在每个树行中找最大值,填充每个节点的下一个右侧节点指针,二叉树的最大深度,最小深度)

文章目录 5.6 515_在每个树行中找最大值5.6.1问题5.6.2解法&#xff1a;层序遍历 5.7 116_填充每个节点的下一个右侧节点指针5.7.1问题5.7.2解法&#xff1a;层序遍历 5.8 116_填充每个节点的下一个右侧节点指针||5.8.1问题5.8.2解法&#xff1a;层序遍历 5.9 104_二叉树的最大…

Transformer的前世今生 day02(神经网络语言模型、词向量)

神经网络语言模型 使用神经网络的方法&#xff0c;去完成语言模型的两个问题&#xff0c;下图为两层感知机的神经网络语言模型&#xff1a; 假设词典V内有五个词&#xff1a;“判断”、“这个”、“词”、“的”、“词性”&#xff0c;且要输出P(w_next | “判断”、“这个”、…

揭秘最热门AI写作软件,看看有哪些值得推荐的AI写作神器

在快节奏的现代生活中&#xff0c;我们常常面临各种压力&#xff0c;例如工作、学习等。因此&#xff0c;一款能够提高写作效率的工具变得尤为重要。那么&#xff0c;有没有什么AI写作软件是比较好用的呢&#xff1f;下面小编给大家推荐几款热门的写作软件。 一.爱制作AI写作 …

什么是分布式

一个系统 各组件分别部署在不同服务器。彼此通过网络通信和协调的系统。 可以指多个不同组件分布在网络上互相协作&#xff0c;比如说电商网站也可以一个组件的多个副本组成集群&#xff0c;互相协作如同一个组件&#xff0c;比如数据存储服务中为了数据不丢失而采取的多个服务…

AI时代,Matter如何融入与服务中国智能家居市场,助力中国企业出海?

随着智能家居产业的飞速发展&#xff0c;丰富多样的智能家居产品为消费者带来了便利的同时&#xff0c;因为不同品牌、不同产品之间的协议与标准不统一&#xff0c;导致消费者体验产生割裂&#xff0c;本来想买个“智能”家居&#xff0c;结果买了个“智障”家居&#xff0c;这…

SQL日期函数

文章目录 1.获取日期时间函数1.1 获取当前日期时间1.2 获取当前日期1.3 获取当前时间 2.日期格式化★★★2.1 日期转指定格式字符串2.2 字符串转日期 3.日期间隔3.1 增加日期间隔 ★★★3.2 减去一个时间间隔★★★3.3 日期相差天数&#xff08;天&#xff09;3.4 相差时间&…

腾讯二面:如何保证接口幂等性?高并发下的接口幂等性如何实现?

什么是接口幂等性 接口幂等性这一概念源于数学&#xff0c;原意是指一个操作如果连续执行多次所产生的结果与仅执行一次的效果相同&#xff0c;那么我们就称这个操作是幂等的。在互联网领域&#xff0c;特别是在Web服务、API设计和分布式系统中&#xff0c;接口幂等性具有非常…

嵌入式软件面试-linux-中高级问题

Linux系统启动过程&#xff1a; BIOS自检并加载引导程序。引导程序&#xff08;如GRUB&#xff09;加载Linux内核到内存。内核初始化硬件&#xff0c;加载驱动&#xff0c;建立内存管理。加载init进程&#xff08;PID为1&#xff09;&#xff0c;通常是systemd或SysVinit。init…

安卓使用MQTT实现阿里云物联网云台订阅和发布主题(3)

一、订阅主题代码讲解 private final String mqtt_sub_topic "/sys/k0wih08FdYq/LHAPP/thing/service/property/set";//订阅话题//mqtt客户端订阅主题//QoS0时&#xff0c;报文最多发送一次&#xff0c;有可能丢失//QoS1时&#xff0c;报文至少发送一次&#xff0c…

23 OpenCV 直方图比较

文章目录 直方图比较的目的相关性计算 (CV_COMP_CORREL)卡方计算 (CV_COMP_CHISQR)十字计算(CV_COMP_INTERSECT)巴氏距离计算 (CV_COMP_BHATTACHARYYA )compareHist 直方图比较算子示例 直方图比较的目的 直方图比较的目的是衡量两幅图像之间的相似度或差异度。通过计算图像的颜…

linux下用docker部署es和kibana(带ik分词器)(二)

在上一篇文章中讲到&#xff0c;我们利用docker安装了es和kibana&#xff0c;下面我们讲解一下在安装es时把ik分词器这个插件集成进去&#xff0c;首先我们编写一个dockerfile文件&#xff0c;自定义一个es镜像&#xff0c;当然这个镜像肯定集成了ik分词器&#xff0c;具体步骤…

【LVGL-开关部件】

LVGL-开关部件 ■ LVGL-开关部件■ 开关部件&#xff1a;指示器打开的颜色■ 开关部件&#xff1a;不可修改■ 开关部件&#xff1a;获取开关状态■ 开关部件&#xff1a;示例一&#xff1a;制冷,制暖,开关 ■ LVGL-开关部件 ■ 开关部件&#xff1a;指示器打开的颜色 ■ 开关部…

探讨Java代码混淆加固工具

摘要 本篇博客将介绍几种常用的Java代码混淆工具&#xff0c;如ProGuard、Allatori Java Obfuscator、VirboxProtector、ipaguard和DashO。我们将深入探讨它们的特点、功能以及在保护Java应用程序安全方面的作用。此外&#xff0c;还将强调在使用Java代码混淆工具时需要注意的…

RK3568笔记二十:PP-YOLOE部署测试

若该文为原创文章&#xff0c;转载请注明原文出处。 注&#xff1a;转换测试使用的是Autodl服务器&#xff0c;CUDA11.1版本&#xff0c;py3.8。 一、PP-YOLOE环境安装 创建环境 # 使用 conda 创建一个名为 PaddleYOLO 的环境&#xff0c;并指定 python 版本conda create -n…

(vue)新闻列表与图片对应显示,体现选中、移入状态

(vue)新闻列表与图片对应显示&#xff0c;体现选中、移入状态 项目背景&#xff1a;郑州院XX项目首页-新闻展示模块&#xff0c;鼠标移入显示对应图片&#xff0c;且体现选中和移入状态 首次加载&#xff1a; 切换列表后&#xff1a; html: <el-row :gutter"20"…

阶乘求和(第十四届蓝桥杯JavaB组省赛真题)

/ 10^9考虑前九位&#xff0c;% 10^9保留后9位 解题思路: 求获取结果的后九位数字&#xff0c;需要对10^9取余&#xff0c;因为202320232023这个数字的阶乘太大&#xff0c;必须要减少计算量&#xff0c;因为当一个整数乘以10^9后对其取余&#xff0c;那么结果都为0。 所以我…

【毕设级项目】基于ESP8266的家庭灯光与火情智能监测系统——文末源码及PPT

目录 系统介绍 硬件配置 硬件连接图 系统分析与总体设计 系统硬件设计 ESP8266 WIFI开发板 人体红外传感器模块 光敏电阻传感器模块 火焰传感器模块 可燃气体传感器模块 温湿度传感器模块 OLED显示屏模块 系统软件设计 温湿度检测模块 报警模块 OLED显示模块 …

FebHost:注册了新加坡.SG域名,还需要申请SSL证书吗?

在互联网飞速发展的今天&#xff0c;网站安全性已经成为评价一个网站是否专业、可靠的重要标准。对于注册了新加坡.SG域名的企业或个人而言&#xff0c;申请SSL证书不仅是保障网站数据安全的关键&#xff0c;更是提升网站在搜索引擎中排名的有效手段。 首先&#xff0c;SSL证书…

osgEarth学习笔记2-第一个Osg QT程序

原文链接 上个帖子介绍了osgEarth开发环境的安装。本帖介绍我的第一个Osg QT程序。 下载 https://github.com/openscenegraph/osgQt 解压&#xff0c;建立build目录。 使用Cmake-GUI Configure 根据需要选择win32或者x64&#xff0c;这里我使用win32. 可以看到include和lib路…