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 9000
        if(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不存在粘包问题。数据整条交付

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【文末附gpt升级4.0方案】英特尔AI PC的局限性是什么

为什么要推出英特尔AI PC&#xff1f; 英特尔AI PC的推出无疑为AIGC&#xff08;生成式人工智能&#xff09;的未来发展开启了一扇新的大门。这种新型的计算机平台&#xff0c;通过集成先进的硬件技术和优化的软件算法&#xff0c;为AIGC提供了更为强大和高效的支持&#xff0…

【探讨】基于卷积神经网络深度学习模型的光场显微三维粒子空间分布重建

光场显微粒子图像测速技术通过单光场相机即可实现微尺度三维速度场的测量&#xff0c;但单光场相机角度信息有限&#xff0c;导致粒子重建的轴向分辨率低、重建速度慢。基于此&#xff0c;提出一种基于卷积神经网络深度学习模型的光场显微粒子三维空间分布重建方法&#xff0c;…

说说你对webpack的理解?解决了什么问题?

文章目录 一、背景二、问题三、是什么参考文献 一、背景 Webpack 最初的目标是实现前端项目的模块化&#xff0c;旨在更高效地管理和维护项目中的每一个资源 模块化 最早的时候&#xff0c;我们会通过文件划分的形式实现模块化&#xff0c;也就是将每个功能及其相关状态数据各…

深入理解:蓝绿部署与金丝雀部署

深入理解&#xff1a;蓝绿部署与金丝雀部署 深入理解&#xff1a;蓝绿部署与金丝雀部署蓝绿部署&#xff08;Blue-Green Deployment&#xff09;原理优缺点适用场景 金丝雀部署&#xff08;Canary Deployment&#xff09;原理优缺点适用场景 总结 深入理解&#xff1a;蓝绿部署…

便捷安全的移动支付方式:扫码登录与支付全面解析

随着移动支付的普及和便利性&#xff0c;扫码登录与支付作为一种快捷安全的支付方式&#xff0c;在各行各业得到了广泛应用。本文将深入探讨扫码登录与支付的原理、优势以及使用场景&#xff0c;帮助读者更好地了解这一便捷的移动支付方式。 ## 扫码登录与支付的原理 扫码登录…

MNN Session 之 CPU 算子(七)

系列文章目录 MNN createFromBuffer&#xff08;一&#xff09; MNN createRuntime&#xff08;二&#xff09; MNN createSession 之 Schedule&#xff08;三&#xff09; MNN createSession 之创建流水线后端&#xff08;四&#xff09; MNN Session 之维度计算&#xff08;五…

Java 程序设计 4 数学函数、字符、字符串

数学函数 Math是final类&#xff0c;在java.lang.Math中&#xff0c;所有数学函数都是静态方法。 Math类中定义了常用的 数学常数 PI : 3.14159265358979323846E : 2.7182818284590452354 方法&#xff1a; 三角函数&#xff1a;sin, cos, tan, asin, acos, atan,toRadians,toD…

mysql分页查询多用GitCode平台

目录 一、在GitCode平台AI搜索结果&#xff08;这个更优&#xff09; 二、在百度搜索输入“mysql Java分页查询”的输出结果&#xff1a; 三、推荐的文章 四、GitCode的使用 1&#xff09;如搜索jdk11可以直接下载jdk11的包 2&#xff09;搜索开源项目 3&#xff09;如搜…

爬虫分析-基于Python的空气质量数据分析与实践

概要 本篇文章利用了Python爬虫技术对空气质量网站的数据进行获取&#xff0c;获取之后把数据生成CSV格式的文件&#xff0c;然后再存入数据库方便保存。再从之前24小时的AQI&#xff08;空气质量指数&#xff09;的平均值中进行分析,把数据取出来后&#xff0c;对数据进行数据…

大数据分析-基于Python的电影票房信息数据的爬取及分析

概要 现如今&#xff0c;人民群众对物质生活水平的要求已不再局限于衣食住行&#xff0c;对于精神文化有了更多的需求。电影在我国越来越受欢迎&#xff0c;电影业的发展越来越迅猛&#xff0c;为了充分利用互联网技术的发展&#xff0c;掌握电影业的态势&#xff0c;对信息进行…

进程的终止

进程的退出&#xff08;main函数的退出&#xff09; main函数的返回值叫做进程的退出码&#xff0c;该退出码表示进程执行的情况。例如&#xff1a;一个函数返回一个值时&#xff0c;我们要知道函数的执行情况&#xff0c;可以去看函数的返回值。 例子&#xff1a; 1 #include…

Redis相关操作高阶篇--集群搭建

Redis相关操作大全一篇全搞定-CSDN博客 Redis集群 是一个由多个主从节点群组成的分布式服务器群&#xff0c;它具有复制、高可用和分片特性。Redis集群不需要seninel哨兵也能完成节点移除和故障转移的功能。需要将每个节点 设置成集群模式&#xff0c;这种集群模式没有中心节…

c++的学习之路:2、入门(1)

一、 C关键字 c的关键字要比c语言要多31个足足有63个&#xff0c;这里我只是了解了下每个有啥作用&#xff0c;具体使用方法以及更多的知识将在后续学习中&#xff0c;慢慢扩展使用&#xff0c;下方表格就是c的63个关键字 asmdoifreturntryautodoubleinlinetypedefdynamic_ca…

LeetCode题练习与总结:接雨水

一、题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3…

【MySQL】3.1MySQL索引的介绍

目录 一、索引的概念 数据库索引 索引的作用 索引的副作用 索引创建的原则&#xff08;应用场景&#xff09; 适合建立索引 二、索引的分类和创建 1.普通索引 创建普通索引 1.1直接创建 1.2修改表结构的方式创建普通索引 1.3创建表时创建普通索引 2.唯一索引 2.1…

如何在Android设备上运行深度网络

返回&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a; 下一篇&#xff1a; 介绍 在本教程中&#xff0c;您将了解如何使用 OpenCV 深度学习模块在 Android 设备上运行深度学习网络。教程是为 Android Studio 2022.2.1 编写的。…

实时数仓之实时数仓架构(Doris)

目前比较流行的实时数仓架构有两类,其中一类是以Flink+Doris为核心的实时数仓架构方案;另一类是以湖仓一体架构为核心的实时数仓架构方案。本文针对Flink+Doris架构进行介绍,这套架构的特点是组件涉及相对较少,架构简单,实时性更高,且易于Lambda架构实现,Doris本身可以支…

c++编写菱形图和计算100~200之间的素数

c编写菱形图 #include <stdio.h> int main() {int i,j,k,n;printf("请输入n:\n");scanf("%d",&n);for(i1;i<n;i){for(k1;k<n-i;k)printf(" ");for(j1;j<2*i-1;j)printf("*");printf("\n");}for(i1;i<…

【Charles如何对手机APP进行抓包和弱网测试】

一、Charles对APP抓包 1、前提条件&#xff1a; 1&#xff09;电脑上必须安装Charles工具&#xff0c;如没有安装可参考&#xff1a;【Charles抓包工具下载安装详细操作步骤】-CSDN博客 2&#xff09;手机和电脑必须在同一个局域网内&#xff08;连接同一个WiFi&#xff09;…

【java多线程】线程基础知识笔记

目录 1、多线程介绍 2、线程 3、线程的调度 4、线程的生命周期 5、线程的并行与并发 6、程的同步与异步 1、多线程介绍 多线程&#xff1a;指的是这个程序&#xff08;一个进程&#xff09;运行时产生了不止一个线程&#xff0c;是Java语言的重要特性&#xff0c;大量应用于…