从数据结构中进一步学习HTTP、TCP协议

261 阅读9分钟

前言

面试中经常会有这样一条要求熟悉HTTP、TCP/IP通信协议,自己一直也没怎么放在心上,觉得只要知道请求报文响应报文(及报文中的内容),大概看的懂Network里各个字段就可以了。

直到有天在一篇公众号文章中看到作者通过对比http1.0http1.1http2.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报文表示同意现在关闭。因此,服务端的ACKFIN一般都会分开发送,从而导致多了一次。

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这八种,其中GETPOST两者区别常考。

  • 请求头

以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具有以下特点:

  1. 内容加密:采用混合加密技术,中间者无法直接查看明文内容;
  2. 验证身份:通过CA证书认证客户端访问的是自己的服务器;
  3. 保护数据完整性:防止传输的内容被中间人冒充或者篡改

具体HTTPS内容可以看下这篇文章blog.csdn.net/xiaoming100…

总结

TCP是传输层协议,约定了连接和传输规范,三次握手成功后,客户端和服务器开始数据交互;HTTP是应用层协议,约定了具体传输内容,也就是数据的规范。

好比TCP协议是修路用的钢筋水泥原材料,连接目的地A到目的地B;HTTP协议是马路及马路上的红绿灯、指示牌,请求响应数据是各式各样的车辆。

以上这些就是自己的一些学习笔记,写的不好,有不对的地方欢迎指出~

参考文章:

mp.weixin.qq.com/s/GTaUaqo3X… blog.csdn.net/qq_39207948…