应用层
应用层认识
1.概念:应用层为我们计算机网络体系结构的最高层,以下的每一层就是为其服务的,说白了就是我们经常接触的那一层,这层也是满足我们日常生活的一些需求的网络程序。
例如:我们经常使用的qq,网站的访问,以及应用软件这一切的都是在应用层。
2.作用:负责应用程序之间的数据沟通,但是对于这些应用程序,它都是又人为编写出来的,所以它就像上面我们写的加法器一样,应该有着自己的协议,有了这些协议,应用层程序之间的交流才会流畅。
应用层协议
应用层的协议有很多,例如:HTTP协议(超文本传输协议)、FTP协议(文件传输协议)、SMTP协议(邮件传输协议)、DNS协议(域名解析协议)等等很多,但是对于http协议,是最常用的应用层协议,所以就首先对http协议进行学习,如下:
HTTP协议
HTTP协议的认识
HTTP协议其实也是一些大佬们设定好的规则,直接提供给我们使用的。 概念:
- 应用层协议,按照应用层的数据格式约定,并且应用层用http协议对应的运输层用到的协议为tcp协议,所以http服务器其实就是一个tcp服务器
- 简单的请求-响应协议(一次请求对应一次响应)。
其中: 请求-响应协议:客户端给服务端发送一个请求,服务器针对请求进行处理,处理完通信结束。 - 明文字符串传输协议。(也就是http协议组织的请求-响应数据实际上是一串字符串,可以直接看见字符串)
HTTP协议的请求格式
一、请求首行:请求中的第一行数据,其中包含三个元素,分别以空格间隔起来,并且以\r\n作为结尾。三个元素分别为请求方法,URL,协议版本
1.请求方法:描述我们请求的目的是什么。(比如:获取数据,删除数据,提交数据还是修改数据等等,我们想要的什么操作) 其中:请求方法中,共有很多种方式,但主要使用的为:GET、HEAD、POST。
1.GET:用于获取数据资源,但是还可以提交少量数据,提交的少量数据保存在URL网址中,但存在一定的长度限制和安全隐患。
- 获取服务器资源。
- 传输少量数据,保存至url中,但是并不安全。
- 请求传输数据有大小限制。
- 请求没有正文。
- 对于参数的数据类型,只接受大多数ASCII字符。
- 会被浏览器主动缓存。
- 提交数据只会产生一个tcp数据包。
2.HEAD:目的与GET相同,但是它的响应不需要正文数据(只要头部描述不需要正文数据)
3.POST:用于提交数据,提交的数据在正文中,长度无限制。
- 向服务器提交数据,修改服务器资源。
- 传输的数据在正文中,很安全。
- 传入数据的大小因不同的浏览器和服务器而不同。
- 请求有正文。
- 对于参数的类型没有限制。
- 请求不会被浏览器主动缓存下来。
- 提交数据会产生两个tcp数据包。其中post会先给服务器发送一个报文通知服务器(我要提交数据的通知),服务器响应后,才会发送真正的报文。
其他还有很多种,如下表格:
2.URL:统一资源定位符,唯一定位网络中的资源。(也就是网址)
下面这幅图,就是一个URL的内容,也就是我们经常使用的内容,其中格式大概分布如下: 定位资源就依靠URL内部所包含的这些元素实现。
具体的格式如下: 协议方案名称 : //用户名 : 密码 @ 域名或者ip地址(图上是服务器地址) : 端口号 /资源路径(图上是带层次的文件路径) ?查询字符串 #片段标识符
-
协议方案名称:也就是我们使用的是什么协议。 -
用户名 : 密码:身份验证信息-用户名和密码,但是一般情况下网址都会隐藏这一部分,因为直接吧用户名和密码放在外面有点子不太安全,所以现在我们很难看见直接用户名和密码。 -
域名:也就是ip地址,也就是我们经常使用的网址。例如:baidu.com就是一个域名,设计成这样便于我们记忆,但是最红还是要被解析成为真正的ip地址。 -
端口号:域名或者io和端口号就定位描述了一台主机上的某一个进程。 其中:http服务默认用80端口号,https默认用443端口号。(https协议是加密协议,较http协议安全一些) -
/资源路径:描述定位指定计算机上的指定路径下的某个实体资源。 其中:/是相对于根目录的,对应服务器上的指定目录。 而域名,端口号,资源路径这三个元素就定位了自定服务器上的指定资源,由指定进程处理。 -
查询字符串:客户端提交给服务端的少量数据。 其中:提交少量数据的格式为:key = val & key = val的这种键值对的方式。 但是对于查询字符串来说,提交数据的时候必须要有规定,有些字符是不能提交的,因为我们也可也看见,在URL的格式中,对于:和//还有?等等一些字符,如果我们在少量数据提交的时候将这些字符写上去,那么就有可能让服务器去解析的时候会出错,所以这个时候就出现了一个URL编码和URL解码 (1)urlencode(URL编码):如果提交的数据中具有特殊字符,就有可能与url中的间隔符造成歧义,那么如果提交中的数据中含有特殊字符,就会被转义(这也是url编码的工作)。其中:遇到特殊字符,则将特殊字符的每个字节转换成为16进制的数字字符(例如:+就转变成为2B),并且在转换之后,为了表示这是编码后的数据,它的前缀会用%进行表示。例如:下图为C++的URL编码形式(可以直接在网路上找到编码和解码的工具): (2)urldecode(URL解码):对URL编码后的数据进行解析成为原始数据,即与编码形式相反,如果解码遇到%的字符,那么就直接将后面的两个字符转换成为16进制的数字(例如:%2B就转换成了2 B),然后根据响应的16进制数字转换成特殊字符的ASCII值。 -
片段标识符:html网页中的一个标签id,可以让网页直接滑动到指定的位置。(就是如果我们在后面设置了片段标识符,那么点开这个网址的时候,鼠标的光标会默认停在网页中我们设置的哪个片段标识符的那个位置)
3.协议版本:也是就我们使用的协议目前的版本。 对于HTTP协调,它的版本分布如下:
- 0.9版:不算成熟的版本,只有GET进行超文本数据的传输,协议的格式并不完善。
- 1.0版:规范了协议的格式,新增支持了GET、HEAD、POST方法,支持了多媒体数据流的传输。
- 1.1版:支持了更多请求方法以及头部字段,有了长连接管理,以及缓存管理。
- 2.0版:基于http协议的臃肿(下面会说),重新进行了一些设计,解决了一些典型问题以及性能问题。
每个版本相较于上一个版本的优化点如下:
1.0版本相较于0.9版本:主要是规范了协议的格式,新增了更多的功能和传输数据的方法。
1.1版本相较于1.0版本:主要是在性能上的改进,以及其他的一些特殊功能的添加。
主要在于: 1.缓存的控制:一些资源在没有改变的情况下不需要进行重新传输。 2.长连接的改进: 其中:因为是长连接的改进,所以在之前的版本中,使用的是短连接。
- 短连接:http协议实际上是基于tcp协议的(传输层用到的协议为tcp协议),所以在通信的时候必须先建立连接。而短连接是建立连接,连接成功发送请求,然后得到响应,断开连接这一个过程。这是一个非常流畅的一次请求与响应的过程,虽然很流畅但是存在弊端,就是性能上不够。
- 长连接:在一次连接中可以进行多次请求,并且在1.1版本的长连接具有管线化管理的思想。
为什么短连接的性能不够呢? 如下图:
主要就是短连接相较于长连接会有建立连接的性能损失,也就是说,短连接每次请求响应后就会断开连接,如果后面还需要什么,只能重新建立连接(而这次建立也只能维持一次响应),而长连接,如图上说的一样,一次响应后不会断开连接,可以继续发送。
长连接的缺陷:因为只是相较于短连接只有新建连接的一个优化,所以在后面的进行请求时还是一次请求对应一次响应,如果这次请求堵塞或者这次响应堵塞,那么后面的请求和响应都无法发送,那么就堵塞了。
所以对于这个原因,就有了管线化思想的: 管线化思想: 优点:相较于长连接,管线化思想的主要就是可以一次性将需要的都进行请求,然后让服务器进行响应即可。 缺点:就是传递的那些请求,是按顺序进行响应,一旦一个请求的响应出现问题,那么后面的响应都会依次堵塞。
所以因此出现了http协议的2.0版本。
2.0版本相较于1.1版本:优化了队头堵塞问题。
队头堵塞问题:就是如果第一个资源处理时间长了,后面的资源就算准备好了,也不能响应,只能等待。
而2.0版本优化如下: 使用了多路复用的手段: 也就是进行请求时,将自己标记起来,然后大家同时发请求,服务器会根据请求的描述信息,进行响应,所以不会存在有堵塞的情况。
而为什么2.0版本基于1.1版本再进行设计就会变得很臃肿呢?
因为对于1.1版本,它的改进已经很大了,例如:长连接,缓存控制,分块传输…等等很多的改变,但是这种改进是一个阶段性的改进,很多字段的都冗余了(比如以前的缓存控制不够完善,就在以前的缓存控制加了个东西成为新的缓存控制),因此在这种阶段性的改进上,http协议会变得非常臃肿,不太合适。
二、头部字段:以key:val键值对组成,每个键值对以 \r\n 结尾,关于请求或者正文等等的一些关键描述信息。 首先我们先看下图: 这是一个http的请求,其中第一行就是我们上面讲的首行部分,从第二行开始,就算头部字段部分:
其中:
- Host:服务器域名或者地址信息。(例如:图上的是 job.xjtu.edu.cu)
- Connection:长短连接管理。
其中:keep-alive表示的是长连接;close表示的是短连接(如图上表示的为keep-alive长连接) - Content-Length:正文描述,描述正文的长度。
其中:这个描述信息是非常重要的,这关乎到请求和响应的成功进行,因为对于请求和响应,服务器必须拿到对应的数据才能进行。而多个请求或者响应连续发送,就会出现粘包问题,如下: 所以,就有了这个字段的产生(用于解决粘包所出现的问题),根据正文长度的描述,进行取数据的时候就可以取出对应的长度正文,解决粘包。 - User-Agent:客户端浏览,以及系统的版本信息。
- Accept:客户端告诉服务器自己能够接收到什么样的响应数据。
- Referer:里面包含一个连接,表示的是当前请求的来源页面连接。
- Contene-Type:正文类型描述,决定了对端如何处理正文数据。
三、空行:也就是\r\n,用于间隔头部与正文。
头部最后一个字段会以\r\n进行结尾,加上空行的\r\n会构成一个连续的\r\n,这是头部结束的标志。 或者当头部字段逐个取出的时候,而其中的某个字段没有其他的信息,只有单纯的\r\n,那么就代表头部结束的标志。(其实都是按照自己的习惯去写的)
四、正文:提交给服务器的数据。(注意:GET的请求没有正文,而POST的提交的数据会放在正文中)
所以,对于GET请求,它的头部字段中的Connect-Length就为0,而POST请求中,它的头部字段中的Connect-Length的大小就为正文的大小。
HTTP响应格式
首先,我们先看一下响应的例图,如下:
一、响应首行:明确对应请求的结果,其中和请求首行数量类似,都包含有三个元素,三个元素以空格间隔,以\n\r结尾。
其中:响应首行包含的三个元素为:协议版本、状态码、状态码描述。
1.协议版本:就是我们上面所讲的HTTP协议版本。 2.状态码:处理结果的简单描述,以数字表示不同的处理结果。(状态码就是一个数字) 其中,分为大致一下几种(其中例如1xx表示的是以1开头的状态码):
- 1xx:表示一些描述和协商信息。(例如:101,表示的是切换协议,服务器根据请求的情况切换协议,但是只能切换成更高级的协议)
- 2xx:响应成功处理。(例如:图上的200,表示OK,证明响应已经成功)
- 3xx:表示资源已经重定向,一个资源从原先的位置移动到另一个位置,但是会保证原来的链接依旧可以用(通常与Location字段一块使用)。
例如: 从新的链接到了旧的链接,那么就会出现一行是Location:新的链接。 其中 ①:对于301状态码:它表示的是永久重定向,则下次请求会直接请求新链接,而不是等待旧链接得到状态码信号后再重定向。 ②:对于302状态码:他表示临时重定向,就是每次请求新链接的时候会先在请求一下原链接。 - 4xx:表示客户端请求错误。(例如:一般我们点开网址有可能会出现404-not found,其实404就是一个状态码,表示不存在这个资源)
- 5xx:表示服务器描述错误。(例如:500-表示服务器遇到了一个未曾预料的状况,导致它无法完成对请求的处理)
3.状态码描述:对于状态码是文字描述。(其实并没有什么实质的作用,,例如图上表示的,200表示的是ok,那么状态码描述就是ok)
二、头部字段:与请求的头部字段格式相同,都是以键值对来组成,以\r\n结尾,主要是描述了一些正文或者响应的关键信息。 其实大多都和请求字段的相同,一个字段对应一个解释,例如:
- Content-Type:描述的是正文信息。(例如:图中的text/html; charset=utf-8,表示的是正文信息写到文档中,并且以utf-8为标准字符)
- Date:表示响应时间。
其他大多数都是一样的,但是在头部字段中,有一个是很重要的,就是Set-Cookie
- Set-Cookie:对于Set-Cookie,这是响应字段的,而与之对应的有一个Cookie是请求字段的,所以我们先了解Cookie。
①:Cookie的由来:由于在早起,http协议是一个无连接的状态,保持的是一次请求,对应一次响应,而响应,而响应完成后,它们就要断开连接,如果我们请求时要输入密码,那么一次请求响应完成后,再请求就又要输入密码,导致很麻烦,而Cookie就是为了解决这个问题而产生了。 ②:Cookie和Set-Cookie的工作原理:在第一次与服务端进行请求和响应的时候,服务端会将客户端的一些状态信息(比如用户名和密码)保存下来,然后通过Set-Cookie字段发送给客户端,此时客户端接收到Set-Cookie的信息后,保存在客户端自己的Cookie中,这样下次请求的时候,直接从Cookie中去取这些状态信息就好了。情况如下图: 其中:login表示可以识别成功。 ③:缺点:由于这个机制,会使得客户端的身份和状态信息一直在和客户端与服务端之间进行交换,这样的话就存在一定的安全隐患。 - session:针对于上面Cokkie机制的缺点,有了缺点就会出现其优化的方向,所以就出来了session机制,这个机制在一定程度上,保护了用户的信息。
session工作原理:当客户端第一次请求服务端的时候,服务端会将客户端的用户信息还有一些状态情况生成一个会话,然后将这个会话保存在服务端的数据库中,因为每个不同的会话都有一个对应的id,所以服务器此时将这个id通过Set-cookie发送给客户端,客户端的Cookie机制将服务器发送的这个id保存在Cookie文件下来,然后客户端再次请求的时候,由于Cookie文件中保存的是id号,所以直接将这个id号发送给服务器,服务器根据id号在自己的数据库中去找,然后根基情况建立连接。
所以说,对于cookie机制,信息是保存至客户端的,而对于session机制,信息是保存至服务端的。
对于头部字段而言,情况还有很多,但是常用的就是上面这些,其他的还可以通过HTTP手册去查找。
三、响应的正文信息:就是服务器响应给客户的信息,此时我们通过代码进行实现,如下: http简单服务器如下: 其中的一些接口使用到了我们之前实现的TCPsocket的类,可以在上一节Tcp套接字是实现中查看。 因为其实,http服务器就是一个tcp服务器,所以可以通过tcp的套接字进行实现。 然后运行这个http服务器: 其中:9000为此次服务器的端口号。 而此时我们通过ifconfig命令去查看当前主机的ip地址,去选择inet的ip地址,但是不能是本地回环地址,如下: 选择这个inet后面的即可,然后打开浏览器,输入ip地址和端口号和想要查询的内容,就会得到以下情况: 这是是服务器的简单抓取请求和响应的一些头部字段和首行。 而此时网络页面会根据我们的正文内容形成: 此时就实现了一个简单的http服务器。
HTTPS协议
HTTPS协议的认识
1.对于https协议,他是对于http协议是有一些优化的,而优化的方面,主要是在保密的方面,而其他都和http协议没什么区别。
2.为什么http协议不安全,会有https协议的诞生呢?
主要是原因: 首先我们先看一个例子,例如:我们在使用http协议的时候,我们一般在聊天的时候,我们就知道我们聊天的对方是谁,而如果我们的建立服务器的时候,被别的黑客进行抓包,这下我们聊天的隐私就被别人窃取了,这也我们在这上面的信息就不在具有意义了。
所以我们每个人在网络上希望我们向公开的东西公开起来,不希望公开的东西不希望有任何人知道,而网络也是如此,有了需求,便有了更新,也是因为如此,https的协议诞生了。
3.https协议与http协议的不同点
- 安全度更高。
- http协议使用的默认端口为80,而https的协议使用的默认端口为443端口。
加密传输
加密传输一共有两个方面,一个是身份验证,一个是加密数据。
1.身份验证:就是引入一个第三方权威认证的专业机构作为第三者,必须都是客户端和服务端两者都信任的双方,双方都在此权威机构上得到身份信息验证,并得到一个身份证书。这样在通信前,双方将自己的身份证书都给对方,对方拿着不是自己的身份证书(是对一些信息,以及时间等等的信息的交代),去权威机构进行身份验证,如果说验证成功,那么就进行通信。否则,就有炸,停止交易。
例如,下图:
这是还没通信时的认证过程,而通信前如下:
上述是一个双向认证的情况,但是我们平时使用的浏览器,都是单向认证的,所以就有了数据加密的方法。
2.数据加密:主要是避免数据被劫持。(因为是单向的请求)
对于数据加密,一共有三种方式:
①:对称加密:使用相同的密钥进行加密。
原理:在通信前,客户端将自己的密钥发给服务端,服务端接收密钥后,然后此时客户端将自己要发送的数据经过密钥的加密后发送给服务端,服务端接收数据后根据客户端给自己发送的密钥进行解密,然后得到数据。
缺点:存在安全隐患。比如:不能每次都使用一种密钥,这样的话非常容易被破解,所以每次通信前都得发送密钥,实现动态的协商。
优点:加密解密的效率一般比较高。
②:非对称加密:加密和解密使用的密钥不同。
原理:对于通信双方(客户端和服务端)都有一对密钥,分别为公钥和私钥(私钥可以解公钥加密的数据),而在通信前,双方都将自己的公钥发送给对方,对方接收到公钥后,将自己的数据用该公钥进行加密,加密完成后,发送给相应的对方,然后各自用各自的私钥去解公钥加密的数据。
缺点:加密解密的效率比较低。
优点:安全度非常高,不怕公钥被劫持。
③:混合加密
原理:通信前,先进行非对称加密,两方将自己的公钥发送给彼此,而彼此拿着公钥加密的对称密钥进行协商,这样密钥就无法被劫持了,最后,两方拿着挟持好的对称密钥进行通信。这种加密方式,不仅保存了安全性,也提高了效率。
ssl加密流程
对于ssl加密,这是https协议的加密,并且这个加密也是针对TCP协议的,因为两者的关系非常密切(应用层的http协议对应的传输层协议一定是tcp协议)。
而ssl加密:它将身份验证和混合加密进行了融合使用。
操作流程如下:
- 服务器(需要被身份验证的一方),生成一对密钥(公钥和私钥)。
- 服务器拿着公钥去第三方权威机构申请一个权威证书。
- 通信时,在tcp通信建立成功后,服务器将自己的权威证书发送给客户端。
- 客户端收到后,先对其进行解析,然后拿着权威证书去第三方权威机构去验证。
- 如果客户端验证成功,会用公钥将自己的所支持的对称加密算法以及一个随机数进行加密并且发送给服务器。
- 服务器接收到客户端发送的数据,使用自己的私钥进行解密,然后识别与客户端所支持对称加密算法列表。
- 服务器将自己所支持的对称加密算法以及一个随机数发送给客户端。
- 客户端与服务器各自根据自己的对称加密算法列表和对方的随机数生成一个对称密钥。
- 往后通信就使用该对称密钥进行。
流程图如下: 1.身份验证阶段:2.交换随机数和支持对称加密算法列表阶段: 3.通信阶段:
|