天天看点

一次完整的http请求全过程(知识体系版)超长文预警

最差的面试体验

面试官评价:除了学历,和培训班出来的没区别。

确实,很多东西我只是会用。面完回来,我发现我确实连一个完整的http请求如何发送都不明白。

失败并不可怕。但是一定得把失败的悲痛化成力量!

我觉得需要把掌握的知识串成一套完整的知识体系。

超长文预警

一次完整的http请求的全过程

域名解析------>tcp建立三次握手过程------>
    发送http请求------>服务器返回html------>
    浏览器根据html构建dom树,cssom树,加载资源------>
呈现给用户
           

简而言之就是这么一句话,也是很多同学会背的一句话。但是如果把这几个阶段拆出来大做文章。那也得需要不少的篇幅。

什么是http

维基百科上的http

超文本传输协议,是一个客户端和服务端之间请求和应答的标准。是一个基于TCP/IP协议、属于应用层的面向对象的协议。客户端发起一个HTTP请求到服务器上指定端口(默认端口是80)。请求和响应消息的头以ascll码的形式给出。

通俗来说:http是网络通信必须遵守的规则,是一个基于请求和响应,无状态的,基于TCP/IP的应用层的协议。

请求和响应:客户端发送请求,服务器端返回响应。

无状态的:协议对于事务处理没有记忆能力,客户端第一次与服务器建立连接发送请求时需要进行一系列的安全认证匹配等,因此增加页面等待时间,当客户端向服务器端发送请求,服务器端响应完毕后,两者断开连接,也不保存连接状态,下一次客户端向同样的服务器发送请求时,由于他们之前已经遗忘了彼此,所以需要重新建立连接。

应用层: Http是属于应用层的协议,配合TCP/IP使用。

TCP/IP: Http使用TCP作为它的支撑运输协议。HTTP客户机发起一个与服务器的TCP连接,一旦连接建立,浏览器(客户机)和服务器进程就可以通过套接字接口访问TCP。

一、域名解析

定义,将域名解析成对应的IP地址。

刁民问:为什么要用域名?不直接使用ip地址?

思考:如果我们要访问百度官网。你觉得是在浏览器中输入www.baidu.com方便,还是输入14.215.177.39方便。再者,服务器端有可能更换ip地址,但是域名的A记录解析到了ip地址。更不更换ip地址都和我们没关系。

答:使用域名更加方便用户记忆。并且服务端如果更换主机,ip地址发生了变化对用户没有影响。不使用域名也无法使用CDN分发网络,必须从网站拿资源,降低了网站的访问速度。

DNS域名解析系统(Domain name system)

为什么要进行DNS域名解析?

网络通信都是基于tcp/ip的,tcp/ip是基于ip协议的。而ip协议只能识别ip地址。所以需要将指定的域名通过DNS解析为ip地址。

dns域名的工作过程?

当DNS客户机需要使用到名称时,它会查询本地DNS服务器来解析该名称。每条查询消息包括三个信息

1、指定的查询域名

2、指定的查询类型

3、DNS指定的查询类别

DNS域名的两种查询方式

递归查询和迭代查询。

两者的查询顺序都是一样的。客户机本地缓存--->本地DNS服务器--->根域名服务器--->顶级域名服务器--->域名提供商

递归查询是将查询结果按照查询过程一层层返回回来,而迭代查询查询到了之后可以直接返回。

DNS域名解析的请求和响应数据报均经过UDP的53端口来发送。

为什么通过udp而不通过可靠的tcp?

udp只需要发送两个报文,请求包,响应包。tcp需要握手三个包,请求包,响应包,挥手四个包。一共九个包相比较之下udp的效率更高。

二、建立tcp连接

讲到TCP,不得不提到的是

TCP和UDP的区别

TCP基于连接,UDP不基于连接

TCP面向字节流,UDP面向报文

TCP只能1对1,UDP可以一对多

TCP首部较大为20个字节,UDP首部只有8个字节

TCP提供可靠的连接,UDP不可靠

为什么TCP可靠?

首先分析TCP报文格式

16位源端口 16位目标端口
32位序号
32位确认序号
4位数据偏移 6位保留位 URG ack psh rst syn fin 16位窗口大小
校验和 紧急指针
选项
数据

源端口号:源端口和IP地址的作用是标识报文的返回地址。

目标端口号:指接收方计算机应用程序接口。

序号:本报文数据组发送的第一个字节的序号

确认号:指明下一个期待收到的字节序号,同时也表明了该序号之前的数据已经准确无误的收到。

数据偏移:有4位,由于报文格式中有选项这个概念,所以TCP报头长度是不确定的。数据偏移实际上是指TCP报头的数据部分在报头的偏移量。4位二进制能表示的最大十进制数字是1111也就是15。又因为数据偏移使用的单位是32位字,所以报文最大长度为15*32/8 = 60字节。

6位保留位:为将来可能出现的功能保留的位置。

URG:紧急指针标志位,URG为1时紧急指针才有效。

ACK:为1时,标志位才有效。

PSH:push,指接收方接收到这个报文字段时,不放入缓存区,直接交付给应用程序

RST:指发生了难以预计的错误需要重置连接

SYN:同步序号,用于建立连接过程

FIN:用于断开连接的标志号。

窗口:滑动窗口大小,用来告诉发送端接受端的缓存大小是多少,从而控制数据传输的速率,进而达到流量控制的目的。

校验和:由发送端计算和存储。由接收端校验。

紧急指针:URG为1时紧急指针有效,是一个正的偏移量。和序号相加为紧急数据最后一个字节的序号。

好了,TCP报文格式分析完了,现在回到我们的问题,为什么TCP的连接是可靠的。

确认和重传机制:三次握手同步双方的序号,确认号,窗口大小,是确认重传和流量控制的基础。

在传输过程中,如果校验和校验失败,丢包或者延时,发送端会立马重传。

数据排序:有专门的序号字段,可以提供数据re-order。

流量控制:窗口字段可以指明双方最大的数据传输和接受量

拥塞控制:由四个核心算法实现:慢启动,拥塞避免,快速重传,快速恢复。

以上就是TCP比UDP更加可靠的原因。

tcp比udp可靠,那么udp可以应用在哪些地方?

tcp(传输控制协议),提供的是可靠的运输,基于连接同时也说明需要的时间更长。应用于需要可靠性较高的场所。http请求,文件传输等等。

udp不基于连接。速度更快,应用于网络通讯速度较快的场景。比如语音电话、视频、直播等等。

TCP讲完了,讲到http请求报文和响应报文

http请求报文格式:请求行,请求头,请求体

请求行:包括四个部分 请求方法、请求地址、空行、协议版本、

说到请求方法,http常用的几种请求方法也是需要知道的。get、post、put、delete、option、head等等。

说到get和post方法,两者有什么区别?

get post
作用 一般用于请求数据或者资源 一般用于提交或者修改数据
使用缓存 可以使用缓存 不可以使用缓存
传递参数 通过url传递参数,有长度限制,只能传递字符串 通过request body传递参数,可以传递各种类型的参数
安全性 不安全(参数明文暴露在url地址中) 较安全
数据包 1个 2个

为什么会产生两个数据包?

发送get请求时,将http header和data一并发送,服务器返回状态码200(ok)

发送post请求时,先发送http header,服务器返回100(continue),然后再发送data(服务器返回200(ok))

请求头:请求报文的一些附加信息。(需要记住一些http常见请求头)

一次完整的http请求全过程(知识体系版)超长文预警

请求头的最后有一行空行表示请求头的结束,这一很重要,必不可少。这是判断请求头是否结束的条件。

请求体:英文(request body)熟不熟悉?没错(看看get和post区别表),post请求就是靠这个来传递参数,而get方法就没有这个请求体;

带上一个简单的post请求实例。

POST  /index.php HTTP/1.1    请求行Host: localhost                 接受请求的ip地址,也可以是域名。User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2 发送请求的应用程序名称 这里根据Mozilla内核和Firefox不难判断是火狐浏览器发送的请求。Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8Accept-Language: zh-cn,zh;q=0.5  可接受的语言格式Accept-Encoding: gzip, deflate   可接受的压缩格式Connection: keep-alive           连接属性Referer: http://localhost/Content-Length:25Content-Type:application/x-www-form-urlencoded  空行username=aa&password=1234  请求数据
           

http响应报文格式:

同样的,http响应报文也包括了四个部分:响应行、响应头、空行、响应体。

响应行:包括协议版本、状态码

响应头:响应报文的一些附加信息(同样的,也需要记住一些常见的响应头)

一次完整的http请求全过程(知识体系版)超长文预警

响应体:返回数据

一个实例

HTTP/1.1200 OK  状态行Date: Sun, 17 Mar 201308:12:54 GMT  响应头部Server: Apache/2.2.8 (Win32) PHP/5.2.5    服务器应用程序是apacheX-Powered-By: PHP/5.2.5Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/Expires: Thu, 19 Nov 198108:52:00 GMT      过期时间Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0Pragma: no-cache Content-Length: 4393   正文长度Keep-Alive: timeout=5, max=100Connection: Keep-AliveContent-Type: text/html; charset=utf-8   返回的正文格式  空行  响应数据HTTP响应示例Hello HTTP!
           

下面到如何发送http请求

首先需要在浏览器中输入url地址,计算机会寻找该url对应的ip地址,首先会在缓存中查找,查找顺序为浏览器缓存---->系统缓存----->路由器缓存,如果没找到就在本地host服务器中查找,如果还没找到就在本地DNS域名服务器中查找。找到url对应的IP地址通过三次握手建立连接。客户端发送一个SYN同步请求,同时客户端进入SYN_SENT状态,服务端接收到数据包,进入SYN_REVD状态,同时返回SYN同步请求和ACK确认号给客户端,客户端接收到ACK确认包进入esdablished就绪状态,服务器端接收到ACK确认包同时进入esdablished就绪状态。客户端根据请求头中的cache-control字段和expires字段判断有没有命中协商缓存,如果没有命中,则发送一个http请求给服务端,服务端根据if-modified、last-modified、etag字段判断有没有命中强缓存。没有命中则从服务器获取数据,根据服务器端返回的html构建dom树和cssom树,合并成渲染树呈现在浏览器页面中,最后加载所需的资源。会话结束通过四次挥手断开连接。请求方发送一个FIN请求释放连接,同时进入FIN_wait1状态,接收方收到FIN进入CLOSE_WAIT状态,表示已经接收到发送方的关闭连接请求,等到接受方的数据发送完毕也要关闭连接时,发送一个FIN给发送方,同时进入CLOSE_WAIT状态,发送方接受到FIN包,返回ACK给接收方同时进入TIME_WAIT状态。接收方收到ACK确认号后进入closed状态,发送方也进入closed状态。

三次握手图

一次完整的http请求全过程(知识体系版)超长文预警
一次完整的http请求全过程(知识体系版)超长文预警

为什么要三次握手?

答:为了防止已经失效的连接请求又传送到了服务端。

如何理解已经失效的连接请求。如果两次握手建立连接,发送第一个连接时,因为网络或其他原因导致请求没有发送到服务端,

从而客户端发送第二个连接请求,建立连接。并且成功与服务端通信,这时服务端收到了第一次发送的连接请求,并且又建立了连接,但是这次连接并不会发送数据而造成不必要的资源消耗。

四次挥手图

一次完整的http请求全过程(知识体系版)超长文预警

刁民问:为什么要四次不是两次?

因为关闭请求方请求关闭只代表没有数据需要传输,但是不能表示接收端的数据传输已经完成了。所以需要四次握手才能完全确定双方的数据已经传输完成。

刁民会问:关闭请求方进入的time_wait状态的意义?

答:确保接收方收到了最后的ACK确认号,如果发送方直接进入CLOSED状态,而接收方没有收到ACK确认号,那么接收方就会一直发送FIN给关闭请求方。

说了http就想说一下http2.0

允许多路复用,在此之前一个连接对应着一个请求,多路复用允许一次连接带有多个请求

二进制分帧,采用新的二进制编码格式将数据分成更小的数据帧

首部压缩,采用了新的HPACK(首部压缩算法),减少了header的大小。

服务器端推送,服务器端主动向客户端推送数据。

说了http就要说https

http的ssl加密是在传输层实现的。

https的安全性更高,端口为443,需要ca证书,在搜索引擎中的排名更高。

https的通信过程。

客户端发送一个https请求,要求建立一个https链接,服务器将网站的ca证书返回给客户端,双方根据安全等级建立会话密钥,服务器端根据公钥加密会话密钥,客户端根据私钥解密会话密钥完成通信过程。

从TCP/IP协议模型的角度来理解HTTP请求和响应如何传递的。

知乎大牛分享

一次完整的http请求全过程(知识体系版)超长文预警

报文到达接收端由低向上的过程叫做数据分用。

tcp/ip结构

一次完整的http请求全过程(知识体系版)超长文预警

七层模型各层作用及协议

一次完整的http请求全过程(知识体系版)超长文预警

从整体架构上来说tcp/ip可以分成(由底向上)链路层、网络层、传输层、应用层。进而又可以细分成osi七层网络模型(由下至上)物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。tcp/ip模型的创建者把osi模型中作用差不多的几层合并起来就成了tcp/ip模型。配合上图食用更加。

一个http请求在tcp/ip模型中完整的过程

一次完整的http请求全过程(知识体系版)超长文预警

http请求从应用层进入传输层,加上tcp首部,添加源和目的端口,通过tcp封装成数据包。

进入到网络层, 为数据包选择路由 相关设备:路由器

进入数据链路层 传输有地址的帧以及错误检测 相关设备:网桥、交换机

物理层 转换成二进制数据在物理媒体上流通 相关设备:中继器、集线器。

传输层经过tcp三次握手。建立了端对端的接口。网络层为数据包分配路由。链路层:传输有地址的帧以及错误检测功能。

物理层将数据以二级制形式在物理媒体上流通。

最后补充一个数据链路层的ARP协议。

地址解析协议:完成ip地址到物理地址的映射。

为什么要完成ip地址到物理地址的映射。

因为以太网协议规定,一台主机要与另一台主机通信,必须要知道目标主机的物理地址。tcp/ip模型中的传输层和网络层只关心目标主机的ip地址。

每一台主机都会在自己的缓存区中建立一个ARP映射表,里面记录着ip地址到MAC地址的映射关系,当客户机需要发送数据时,先检测ARP缓存表中有没有对应的MAC地址,如果有则直接发送,如果没有,则向该网段所有主机发送ARP数据包,里面含有客户主机IP地址、客户主机MAC地址和目标主机的MAC地址,网段的其他主机收到ARP数据包后检查本地ip地址是否和ARP数据包中的IP地址相对应。如果不对应则直接忽略,如果对应,将客户主机的IP地址和MAC地址写入自己的ARP缓存表中,然后将自己的MAC地址写入ARP请求包中作为ARP响应包返回。客户主机收到响应包将MAC地址写入ARP缓存表中。

广播发送请求,单播返回响应。

继续阅读