前言
面试中经常会有这样一条要求熟悉HTTP、TCP/IP通信协议
,自己一直也没怎么放在心上,觉得只要知道请求报文、响应报文(及报文中的内容),大概看的懂Network
里各个字段就可以了。
直到有天在一篇公众号文章中看到作者通过对比http1.0
、http1.1
和http2.0
来说明队列
这种数据结构,才意识到自己对网络协议知识的浅薄。所以想在此记录一下在那之后关于HTTP和TCP协议
的学习体会。
TCP协议
1. TCP协议的定义
TCP,面向连接的传输层协议。每一条TCP连接只能有两个端点,也就是点对点传输。通过TCP连接传输的数据,无差错、不丢失、不重复、并且按序到达。
2. TCP是如何建立连接传输的
2.1 三次握手

图中说明已经比较清楚了,每个字符码对应不同的含义和状态(我反正一直只记住了SYN=1
表示建立连接,ACK=1
表示确认)。
这里补充个说烂了的问题:为什么第二次握手中ACK为1,表示服务端确认应答后,还需要第三次握手呢?
答:为了防止已失效的链接请求报文突然又传到了服务端,因而产生错误。
怎么理解已失效的链接呢?我画了一张图:

由于客户端已不需要这次请求了,它就不响应服务器。但是服务器以为新的连接已经建立好了,等着你客户端发来数据。这样就会导致服务器的许多资源就这么浪费了。
所以当服务器收不到第三次握手的连接确认时,就明白了不需要建立连接。
2.2 四次挥手

如图所示,TCP连接是双向的,在四次挥手中,前两次挥手用于断开客户端——服务器
的连接,后两次挥手用于断开服务器——客户端
的连接。同样提个基础问题:为什么是四次挥手?
答:客户端主动关闭连接时,服务器收到客户端的FIN
报文时,仅表示客户端不再发送数据了但是还能接收数据,服务端ACK
报文通知客户端你断开吧;同时服务端也未必全部数据都发送给对方了,所以服务端可以立即关闭,也可以发送一些数据给对方后,再发送FIN
报文表示同意现在关闭。因此,服务端的ACK
和FIN
一般都会分开发送,从而导致多了一次。
HTTP协议
1. HTTP协议的定义
HTTP
,超文本传送协议(Hypertext Transfer Protocol )是应用层协议。代表在浏览器请求和服务器响应这种交互行为中,必须按照一定的格式和规则。HTTP
的特点是无连接、无状态。(什么鬼,它不就是用来连接浏览器和服务器的吗?别急,接着往下看)
1.1 无连接
无连接是指限制每次连接只处理一个请求,服务器处理完客户端的请求,并收到客户端的应答后,会断开连接。HTTP
的设计者有意利用这种特点将协议设计为请求时建连接、请求完释放连接,以尽快将资源释放出来服务其他客户端。
1.2 无状态
无状态是指同一个客户端第二次访问同一个服务器上的资源时,服务器的响应与第一次被访问的时候一样,但是服务器并不知道你曾经访问过,也不记得你曾经访问过多少次。
所以它不会受前面的请求应答情况直接影响,也不会直接影响后面的请求应答情况。这一特性简化了服务器的设计,使服务器更容易支持大量并发的HTTP
请求。
但HTTP无状态不代表HTTP
的应用也是无状态的,当使用了cookie和session机制的时候,使用HTTP
的应用也能有状态。
2. HTTP报文
报文分请求报文和响应报文两类。
2.1 请求报文
请求报文由请求行
、请求头
、空行
和请求体
组成。
- 请求行
由请求方法、URI和HTTP协议版本3个字段组成,它们之间用空格分隔。
请求方法一般是GET、POST、DELETE、PUT、OPTIONS、TRACE、CONNECT和HEAD这八种,其中GET
和POST
两者区别常考。
- 请求头
以key-value的形式,告知服务器所有有关于客户端请求的信息。这里举常见的几个:
User-Agent
:产生请求的浏览器信息;
Accept
:客户端可识别的内容类型列:text/html, application/xhtml+xml, application/xml
Host
:请求的主机名
Accept-Encoding
:客户端可接受的编码压缩格式
Cookie
:浏览器与服务器数据交互拓展方式
- 空行
内容分隔,表示请求头到此结束。
- 请求体
请求的数据(参数)
2.2 响应报文
与请求报文对应,响应报文也分为四部分,分别是状态行
、响应头
、空行
和响应体
- 状态行
主要内容是状态码,常见的状态码有:
200
----请求成功;
304
----请求资源指向缓存;
401
----请求授权不通过;
403
----服务器收到请求,但资源禁止访问;
404
----资源不存在(一般是url错误)
500
----服务器报错
- 响应头
Content-Type
:返回的资源类型
Content-Encoding
:返回的编码压缩格式
Cache-Control
:缓存控制;
Expires
:设置过期时间;
- 空行
内容分隔
- 响应体
响应体就是响应的消息体。如果是纯数据就是返回纯数据,如果请求的是HTML页面,那么返回的就是HTML代码等。
3. HTTP1.0、HTTP1.1、HTTP2.0和HTTPS的区别
3.1 HTTP1.0
HTTP1.0
被抱怨最多的就是连接无法复用,和队头阻塞这两个问题。
因为客户端是依据域名来向服务器建立连接,一般PC端浏览器会针对单个域名的server同时建立6~8个连接。
无法复用导致每次连接都需要三次握手;
队头阻塞导致带宽作用不能充分发挥,后续请求一直等待。队头阻塞的根本原因是使用了队列
这种数据结构,遵循先进先出(FIF0)
的原则,只有前一个请求的响应收到了,才能发送下一个请求,而且这个阻塞主要发生在客户端。
3.2 HTTP1.1
HTTP1.1
改进了1.0中每次请求都需要建立一个TCP连接的规则,默认每次连接都是长连接,使用管道(Pipeline)
的概念,解决了HTTP1.0客户端的队头阻塞
。对于同一个TCP连接,允许一次发送多个HTTP1.1请求,也就是说,不必等前一个响应收到,就可以发送下一个请求了。
但是HTTP1.1规定服务器响应发送顺序必须按照对应的被接受请求的顺序,也就是说最先收到的请求处理时间长了,响应生成也就慢了,虽然后面的响应已经完成,但也会一直等待。这就造成了服务器端的队头阻塞。
3.3 HTTP2.0
为了解决服务器端队头阻塞,HTTP2.0采用了二进制分帧
和多路复用
。
- 二进制分帧
HTTP2.0
采用二进制格式传输数据,而非 HTTP 1.x
的文本格式,二进制协议解析起来更高效。HTTP2.0
中,同域名下所有通信都在单个连接上完成,该连接可以承载任意数量的双向数据流。每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装。
- 多路复用
HTTP2.0
允许同时通过单一的TCP连接发起多重的请求--响应消息。即某个请求任务耗时严重,不会影响到其它连接的正常执行。
除了二进制分帧
和多路复用
,HTTP2.0还具有首部压缩
和服务器推送
两个特性。
- 首部压缩
HTTP2.0
对消息头采用HPACK(专为http/2头部设计的压缩格式)进行压缩传输,能够节省消息头占用的网络的流量。而HTTP/1.x
每次请求,都会携带大量冗余头信息,浪费了很多带宽资源。
- 服务器推送
我觉得和ssr
有些类似吧。
服务器可以在发送页面HTML时主动推送其它资源,而不用等到浏览器解析到相应位置,发起请求再响应。如果一个请求是由你的主页发起的,服务器很可能会响应主页内容、logo以及css文件,这相当于在一个 HTML 文档内集合了所有的资源。并且可以缓存在服务器。
3.4 HTTPS
HTTP协议
传输的数据都是未加密的,也就是明文的,因此使用HTTP协议
传输隐私信息非常不安全;而HTTPS
基于HTTP
协议,通过SSL或TLS提供加密处理数据、验证对方身份以及数据完整性保护。
HTTPS
具有以下特点:
- 内容加密:采用混合加密技术,中间者无法直接查看明文内容;
- 验证身份:通过CA证书认证客户端访问的是自己的服务器;
- 保护数据完整性:防止传输的内容被中间人冒充或者篡改
具体HTTPS
内容可以看下这篇文章blog.csdn.net/xiaoming100…
总结
TCP
是传输层协议,约定了连接和传输规范,三次握手成功后,客户端和服务器开始数据交互;HTTP
是应用层协议,约定了具体传输内容,也就是数据的规范。
好比TCP协议
是修路用的钢筋水泥原材料,连接目的地A到目的地B;HTTP协议
是马路及马路上的红绿灯、指示牌,请求响应数据
是各式各样的车辆。
以上这些就是自己的一些学习笔记,写的不好,有不对的地方欢迎指出~
参考文章: