网络基础之应用层协议
📌————本章重点————📌 🔗了解应用层的概念; 🔗了解网络传输过程中的数据组织方式; 🔗掌握HTTP与HTTPS协议基本概念; 🔗了解具体应用场景; ✨————————————✨
应用层介绍
应用层是什么
我们在之前的文章里讲过,应用层是应用在各个程序之间的数据沟通,其实应用层协议是面向程序员的,因为这些协议都是程序员写的,是方便程序员在编写程序时完成各个应用程序之间的沟通
组织方式
序列化
在网络传输或者数据的持久化储存的时候,将多个数据对象按照指定格式进行组织成一个二进制数据进行传输或者持久性的过程
反序列化
对二进制数据按照指定格式进行解析得到各个数据对象的过程
进行自定制协议主要要考虑的要素:
1.传输性能: 定制一个协议,传输数据要尽可能的快,数据要尽可能的短小,比如我要告诉你我要去吃饭,如果发送一个字符串,传输性能会很差,如果我使用1代表这句话,我们就只需要传输1就可以代表这句话。
2.解析性能: 传输多个数据对象的时候要进行序列化,对方拿到数据之后也要进行反序化,所以解析性能就是序列化和反序列化所消耗的时间 以上会在解析的情况下很慢,传输多个对象的时候要进行数据传输
3.调试便捷性: 更多的是对于程序员的可见性,比如我在编写的时候出错方便调试
常见的自定义序列化方式
1.使用字符串进行组织
2.使用二进制进行序列化,将三个对象的二进制数据分别放到一整块内存的指定位置,最后按照指定的位置进行解析,常用的有结构体序列化,在结构体定义的时候是空间的开辟过程,在结构体中赋值的过程,就是数据组织的过程,所以结构序列化的解析性能是非常高的
在字符串序列化过程中是可见的,使用二进制序列化的话是在内部完成。不同的序列化有不同的优点,传输性能和解析性能侧重点不同,利用领域也不同,比较典型的序列化方式有: json序列化,protobuf序列化,二进制结构体序列化…
举例
网络计算器:例如, 我们需要实现一个服务器版的加法器. 我们需要客户端把要计算的两个加数发过去, 然后由服务器进行计算, 最后再把结果返回给客户端.一般情况下,接收信息和计算不会放到同一个服务器中,可能会发生数据丢失,一般情况下会再给一个计算服务器专门进行运算
约定方式一:二进制结构体序列化演示:
结构体的定义:
struct cal_t {
intt num1;//数据1
int num2;//数据2
char op;//计算方式
}
数据的发送:
(以下代码部分是更具之前的博客tcp那一章封装的)
while(1){
struct cal_t cal;
cal.num1 = 11;
cal.num2 = 22;
cal.op = '+';
int fd = cli_sock.fd();
send(fd,&cal,sizeof(cal),0);
int res;
recv(fd,&res,4,0);
std::cout << "res:"<<res<<std::endl;
}
数据的接收过程:
std::cout << "new client: "<<cli_ip<<":"cli_port<<std::endl;
while(1){
struct cal_t cal;
int fd = new_sock,fd();
recv(fd,&cal,sizeof(cal),0);
int res = -1;
switch(cal.op){
casse '+':
res = cal.num1+cal.num2;
break;
default:
break;
}
send(fd&res,sizrof(res),0);
new_sock.close();
}
约束方式二:
客户端发送一个形如"1+1"的字符串;
这个字符串中有两个操作数, 都是整形;
两个数字之间会有一个字符是运算符, 运算符只能是 + ;
数字和运算符之间没有空格;
…
在我+们网络传输的过程中,只要是内存中的数据都可以进行传输,不关心数据的组织方式是怎么样的。因为网络传输是主机传输,所以我们需要考虑以下问题:
1.结构体内存对齐,两端主机采用同样的对齐方式
2.传输的过程字节序的问题,所以要将数据转化为网络字节序进行传输
HTTP协议——超文本传输协议(最早就是用来传输web网页传输的)
HTTP协议的特性
1.是基于tcp协议的,传输可靠安全
2.是基于字符串明文传输,调试便捷性高
3.是一种简单的请求—响应协议(早起是断链接,一次请求响应后关闭)
HTTP协议的格式:
请求行(首行):请求中的第一行,主要对请求进行关键性描述
请求头部:都是一个个的键值对,是对请求的附加描述以及对正文的描述,每个属性以\n进行分隔
空行:间隔头部与正文
正文:提交给服务器的数据
HTTP 请求
请求行
请求行中的内容分为三个部分,以空格间隔,请求行以\r\n作为结尾(请求行一般就是刚好一行数据)
第一部分:请求方法
GET:向服务器请求一个网页实体资源,是没有正文的,也可以向服务器提交数据,提交的数据在url中的,获得的url长度有限,有些是1kb,4kb,8kb,每个地方不一样
POST:向服务器提交表单数据,请求中有正文
HEAD:(在面试中经常会问GET和HEAD有什么区别,作用于GET类似,但不同的是,实际上HEAD要的是头部描述,不要实体资源)
PUT:更新服务器的资源
DELETE:删除服务器上的资源
第二部分:URL(统一资源定位符)
url就是我们经常说的“网址”,功能就是定位网络上某一台主机上的某个资源
服务器地址(域名):ip地址才是网络上一台主机的标识但是ip地址不容易记忆,所以就设计了域名系统,以便于记忆的字符串作为域名,通过域名上网的时候,先进过域名系统进行域名解析,得到服务器的ip地址,然后通过ip地址进行访问。在win系统下的文件夹记录了域名和ip地址的映射关系,如果将其修改,就无法进行访问。
port:在我们浏览网页的时候,在网址中并没有看到端口,这是因为http服务器默认使用80端口(https:443)
资源路径:是一个相对资源路径,这样用户不能随意访问服务器上的文件,智能访问相对应目录中的所有文件9
urlencode: url编码,目的就是将查询字符串或者资源路径中特殊的字符进行编码转移,编码格式:将特殊字符值转化为16进制的ASCII字符,前缀为 %
(像 / ? : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现.比如, 某个参数中需要带有这些特殊字符,
就必须先对特殊字符进行转义.转义的规则如下:将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成%XY格式,urldecode就是urlencode的逆过程;)
ch :#之后的数据,叫做片段标识符通常用于定位网页中的某个id标签,用于打开网页后直接跳转至指定位置
第三部分:协议版本
Header: 请求的属性,以冒号分隔和空格的键值对,每组属性之间采用\n进行分隔,遇到空行表示Header部分结束,是对于请求的附加描述和正文描述。
请求头部(只会在请求中出现的头部字段,描述请求)
正文头部(在请求和响应中都会出现,主要是对于正文的描述)
响应头部(只会在响应中出现的头部字段,描述响应)
**通用头部(**在请求和响应中都会出现,属于本次通信或者链接的一些描述)
Body:空行后边的内容都是body,body允许空字符串,如果cody存在,那么header中会有一个content—length属性来标识body的长度
HTTP常见Header
connection:keep—alive/close;可以控制长链接还是短链接
Content-Type: 数据类型(text/html等),就是服务器收到信息后如何进行解析处理
Content-Length: Body的长度
Host: 客户端告知服务器, 所请求的资源是在哪个主机的哪个端口上;
User-Agent: 声明用户的操作系统和浏览器版本信息;
referer: 当前页面是从哪个页面跳转过来的;
location: 搭配3xx状态码使用, 告诉客户端接下来要去哪里访问;
Cookie: 用于在客户端存储少量信息. 通常用于实现会话(session)的功能;
HTTP常见状态码
重定向:最初设计的目的是:一个请求,要请求的资源被移动到了其他位置,重定向到其他链接。比如我们要请求a.png这个文件,但是每个文件都存放在根目录也不行,我们将其放入image/a.png这个文件夹中,想要依然保持原链接有效,我们要进行重定向。
HTTP响应
响应首行是:[版本号] + [状态码] + [状态码解释]http版本各个版本号的区别于介绍
协议切换: 我们经常使用的http协议,我们发一个协议你才能给我进行一个回复,服务器无法主动给客户端发送消息,比如经常使用的网页聊天功能,所以后来就有人设计了一个websocke协议,建立了一个长链接,如果服务器需要给客户端发送消息的话,就会切换到websocket协议。
头部字段中的cookie(请求头)和set-cookie(响应头)
http是一个简单的请求——响应协议,不管是短连接还是长链接,链接都不是一直持续的。
这样就会存在一个问题:比如在网站购物,因为链接不是持续的,导致每次买东西都要重新建立链接进行登录。因此,不管链接是不是原来的,但是都要分辨出用户,为了解决这个问题就提出了一个方案:cookie机制
cookie是一种信息缓存机制,将一些信息保存到客户端主机上,等下一次请求服务器的时候读取出来发送给服务器
第一次登录将用户名等信息缓存至本地,在下次再进行请求的时候就会从本地中取出来,在多次通信中不断维护客户端的状态。但是这样存在缺陷:不安全。很多敏感信息容易被劫持,因此,不能将敏感信息进行传输,所以提出了session(会话)机制。
session会话:就是为客户端和服务器的通信建立一个会话,将会话重要内容保存起来,会话内容被保存在服务器上,通过cookie只需要传输session_id即可,将敏感信息保存起来。session会话机制是在cookie机制的基础上,避免了敏感信息的传输,提高了安全性。
session和cookie简单区别
1.cookie是将关键信息保存在客户端本地,每次通信前发给服务器
2.session是将会话信息保存在服务器,通过session_id进行cookie传输,保存隐私性
本质上来说还是有一些安全隐患的,比如:cookie篡改
HTTPS协议:
https协议:在http协议的基础上进行了一层加密,因此https不是一个新的协议,而是一个加密后的协议。
加密:ssl/tls(安全套接层)加密
为什么要进行加密:
1.身份验证: 在进行网络通信的时候要知道对方是谁,并且还要可以验证通信的就是正确的。第三方权威机构+ca验证。通信前进行解析证书,查看证书中的权威机构是否是自己信任的权威机构,查看证书有没有被修改,确认对方的身份信息
2.加密传输: 对数据的传输进行加密
通信双方进行传输加密,需要进行一个密钥的协商,容易被黑客进行劫持。
3.加密方式
(1)对称加密: 数据的加密和解密使用的是相同的密钥
缺点:进行密钥协商的时候容易被劫持,加密形同虚设
优点:加解密的效率高
(2)非对称加密:数据的加密和解密使用的密钥是不一样的
缺点:加解密的效率是比较低下的
优点:安全,不怕被劫持
思想:通过指定的算法(RSA),可以生成一对密钥(公钥和私钥),使用公钥进行加密,使用私钥进行解密
流程:链接建立成功之后,将自己的公钥发送给对方,对方使用公钥加密传输的数据,这个数据只能使用私钥进行解密
(3)混合加密: 假设是客户端对服务器进行验证
1.生成一对非对称密钥,链接建立成功,通信前将公钥发送给对方(所以这时候一开始的时候私钥是掌握在服务器的手中的,只有服务器能进行解密)
2.客户端收到后,使用公钥进行加密一个随机数a,以及自己支持的对称加密算法
3.服务器收到之后使用私钥进行解密,得到了随机数a和对方所支持的对称加密算法
4.服务器向客户端发送一个随机数b,以及自己支持的对称加密算法,客户端和服务器,各自根据两个随机数和支持的对称加密算法,计算出一个对称密钥(密钥的协商就完毕了)
5.往后的通信使用堆成密钥进行加密解密
CA证书
在实际的ssl加密中,身份验证和加密传输是聚合在一起的,即包含在CA证书中,CA证书中包含了更多的关于通信方的公钥,机构信息,证书颁发机构信息,失效时间…
整体流程: 单向验证,以服务器验证为主
- 服务器自己生成了一对密钥,拿着公钥去第三方权威机构颁发证书
- 权威机构根据服务器的公钥,生成一个CA证书给服务器
- 客户端与服务器建立链接后,通信前,服务器会将CA证书发送给客户端
- 客户端收到CA证书,进行解析验证权威机构是否自己信任,在权威机构验证身份后,解析出公钥
- 客户端随机生成一个随机数,使用公钥对随机数+加密算法进行加密,发送给服务器
- 服务器收到数据之后,使用私钥进行解密,生成一个随机数,将随机数和加密算法发给客户端
- 客户端收到数据后,客户端和服务器都有对方的随机数和自己的随机数,以及加密算法,进行计算得到一个对称密钥
- 往后的通信,使用堆成密钥进行加密传输