速记:一个http请求的全过程是怎样的?

一个http请求的全过程是怎样的?

一、前言

  当我们在浏览器栏输入:http//:www.baidu.com 的时候,具体发生了什么呢?这个请求是怎么到达服务器及返回结果的呢

              http请求过程图示                  

二、概述

  1. 浏览器进行DNS域名解析(就是域名到IP地址的转换过程),得到对应的IP地址
  2. 根据这个IP,找到对应的服务器建立连接(三次握手)
  3. 建立TCP连接后发起HTTP请求(一个完整的http请求报文)
  4. 服务器响应HTTP请求,浏览器得到html代码(服务器如何响应)
  5. 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等)
  6. 浏览器对页面进行渲染呈现给用户
  7. 服务器关闭TCP连接(四次挥手)

三、过程详解

1.DNS域名解析

  1. 首先会搜索浏览器自身的DNS缓存(缓存时间比较短,大概只有1分钟,且只能容纳1000条缓存);
  2. 如果浏览器自身的缓存里面没有找到,那么浏览器会搜索系统自身的DNS缓存;
  3. 如果还没有找到,那么尝试从 hosts文件里面去找;
  4. 在前面三个过程都没获取到的情况下,浏览器就会发起一个DNS的系统调用,就会向本地配置的首选DNS服务器(一般是电信运营商提供的,也可以使用像Google提供的DNS服务器)发起域名解析请求(通过的是UDP协议向DNS的53端口发起请求,这个请求是递归的请求,也就是运营商的DNS服务器必须得提供给我们该域名的IP地址)。

2、TCP三次握手

  三次握手: 服务端新建套接字,绑定地址信息后开始监听,进入LISTEN状态。客户端新建套接字绑定地址信息后调用connect,发送连接请求SYN,并进入SYN_SENT状态,等待服务器的确认。服务端一旦监听到连接请求,就会将连接放入内核等待队列中,并向客户端发送SYN和确认报文段ACK,进入SYN_RECD状态。客户端收到SYN+ACK报文后向服务端发送确认报文段ACK,并进入ESTABLISHED状态,开始读写数据。服务端一旦收到客户端的确认报文,就进入ESTABLISHED状态,就可以进行读写数据了。

    1. 为什么握手是三次,而不是两次或者四次?

   答:两次不安全,四次没必要。tcp通信需要确保双方都具有数据收发的能力,得到ACK响应则认为对方具有数据收发的能力,因此双方都要发送SYN确保对方具有通信的能力。

    2. 三次握手可以携带数据吗?

    答:第一次、第二次握手不可以携带数据,而第三次握手是可以携带数据的。假设第一次可以携带数据,如果有人恶意攻击服务器,每次都在第一次握手中的SYN报文放入大量数据,重复发送大量SYN报文,此时服务器会花费大量内存空间来缓冲这些报文,服务器就更容易被攻击了。

    3. TCP三次握手失败,服务端会如何处理?

    答:握手失败的原因有两种,第一种是服务端没有收到SYN,则什么都不做;第二种是服务端回复了SYN+ACK后,长时间没有收到ACK响应,则超时后就会发送RST重置连接报文,释放资源。

    4. ISN代表什么?意义何在?ISN是固定不变的吗?ISN为何要动态随机

    答:ISN全称是Initial Sequence Number,是TCP发送方的字节数据编号的原点,告诉对方我要开始发送数据的初始化序列号。

    ISN如果是固定的,攻击者很容易猜出后序的确认号,为了安全起见,避免被第三方猜到从而发送伪造的RST报文,因此ISN是动态生成的。

    5. 什么是半连接队列

    答:服务器第一次收到客户端的SYN之后,就会处于SYN_RECD状态,此时双方还没有完全建立连接。服务器会把这种状态下的请求连接放在一个队列里,我们把这种队列称之为半连接队列。当然还有一个全连接队列,就是已经完成三次握手,建立起来连接的就会放在全连接队列中,如果队列满了就有可能出现丢包现象。

3、 发起HTTP请求

   HTTP是一个客户端和服务器端请求和应答的标准(TCP)。客户端是终端用户,服务器端是网站。通过使用web浏览器、网络爬虫或者其它的工具,客户端发起一个到服务器上指定端口(默认端口为80)的HTTP协议进行,否则无法连接。

  通俗来讲,他就是计算机通过网络进行通信的规则,是一个基于请求与响应,无状态的,应用层的协议,常基于TCP/IP协议传输数据。目前任何终端之间进行任何一种通信都必须按照HTTP协议进行,否则无法连接。

    HTTP请求报文:

    一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成。

 1)请求行

  请求行分为三个部分:请求方法、请求地址和协议版本。

  请求方法

  HTTP/1.1 定义的请求方法有8种:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。

  最常用的两种GET和POST,如果是RESTful接口的话一般会用到GET、POST、DELETE、PUT。

    请求地址

    URL:统一资源定位符,是一种自愿位置的抽象唯一识别方法。

    组成:<协议>://<主机>:<端口>/<路径>。

    端口和路径有时可以省略(HTTP默认端口号是80)。

    2)请求头部

    请求头部为请求报文添加了一些附加信息,由“名/值”对组成,每行一对,名和值之间使用冒号分隔。

    请求头部的最后会有一个空行,表示请求头部结束,接下来为请求数据,这一行非常重要,必不可少。

    3)请求数据

    可选部分,比如GET请求就没有请求数据。

4、服务器响应HTTP请求

   接收到HTTP请求之后,就轮到负载均衡登场了,它位于网站的最前端,把短时间内较高的访问量分摊到不同机器上处理。负载均衡方案有软件、硬件两种。软件方案常见的就是NGINX了。

   Nginx的作用主要有两个1,处理静态文件请求,2转发请求给后端服务器。然后后端服务器查询数据库返回数据。数据返回给客户端仍然通过HTTP协议传输。

    HTTP响应报文主要由状态行、响应头部、空行以及响应数据组成。

    1.状态行:由3部分组成,分别为:协议版本,状态码,状态码描述。

    其中协议版本与请求报文一致,状态码描述是对状态码的简单描述,所以这里就只介绍状态码。

    一些常见的状态码如下:

      2)响应头部

    与请求头部类似,为响应报文添加了一些附加信息。

    3)响应数据

    用于存放需要返回给客户端的数据信息。

  上面的 HTTP 响应中,响应头中的 Content-Length 同样用于表示消息体的字节数。Content-Type 表示消息体的类型,通常浏览网页其类型是HTML,当然还会有其他类型,比如图片、视频等。

5、浏览器解析

    浏览器拿到index.html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,就向服务器端去请求下载(会使用多线程下载,每个浏览器的线程数不一样),这个时候就用上keep-alive特性了,建立一次HTTP连接,可以请求多个资源,下载资源的顺序就是按照代码里的顺序,但是由于每个资源大小不一样,而浏览器又多线程请求请求资源,所以显示的顺序并不一定是代码里面的顺序。

  浏览器在请求静态资源时(在未过期的情况下),向服务器端发起一个http请求(询问自从上一次修改时间到现在有没有对资源进行修改),如果服务器端返回304状态码(告诉浏览器服务器端没有修改),那么浏览器会直接读取本地的该资源的缓存文件。

6、浏览器进行页面渲染

    最后,浏览器利用自己内部的工作机制,把请求的静态资源和html代码进行渲染,渲染之后呈现给用户,浏览器是一个边解析边渲染的过程。

7、服务器关闭TCP连接

    一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接。而关闭TCP连接就需要进行四次挥手了。

    中断连接端可以是客户端,也可以是服务器端。

    四次挥手:

    注:SYN:同步位,SYN=1,表示要进行一个连接请求;

      FIN:表示关闭连接;

      ACK:表示响应,确认位,ACK=1,确认有效,ACK=0,确认无效;

      seq:序号,机器随机生成;

      ack:确认号,对方发送序号+1(ack=seq+1);

      PSH:表示有 DATA数据传输;

      RST表示连接重置。

      其中,ACK是可能与SYN,FIN等同时使用的,比如SYN和ACK可能同时为1,它表示的就是建立连接之后的响应;如果只        是单个的一个SYN,它表示的只是建立连接。但SYN与FIN是不会同时为1的,因为前者表示的是建立连接,而后者表示的是断开连接。RST一般是在FIN之后才会出现为1的情况,表示的是连接重置。

1. 为什么握手是三次,而挥手时需要四次呢?

    答:其实在TCP握手的时候,接收端将SYN包和ACK确认包合并到一个包中发送的,所以减少了一次包的发送。对于四次挥手,由于TCP是全双工通信,主动关闭方发送FIN请求不代表完全断开连接,只能表示主动关闭方不再发送数据了。

    而接收方可能还要发送数据,就不能立即关闭服务器端到客户端的数据通道,所以就不能将服务端的FIN包和对客户端的ACK包合并发送,只能先确认ACK,等服务器无需发送数据时在发送FIN包,所以四次挥手时需要四次数据包的交互。

2. TIME_WAIT状态有什么作用,为什么主动关闭方没有直接进入CLOSED状态释放资源?

    答:如果主动关闭方进入CLOSED状态后,被动关闭方发送FIN包后没有得到ACK确认,超时后就会重传一个FIN包。如果客户端没有TIME_WAIT状态而直接进入CLOSED状态释放资源,下次启动新的客户端就可能使用了与之前客户端相同的地址信息,有两个危害:

3. 为什么TIME_WAIT状态需要经过2MSL才能进入CLOASE状态?

    答:MSL指的是报文在网络中最大生存时间。在客户端发送对服务端的FIN确认包ACK后,这个ACK包有可能到达不了,服务器端如果接收不到ACK包就会重新发送FIN包。

    所以客户端发送ACK后需要留出2MSL时间(ACK到达服务器器+服务器发送FIN重传包,一来一回)等待确认服务器端确实收到了ACK包。也就是说客户端如果等待2MSL时间也没收到服务器端重传的FIN包,则就可以确认服务器已经收到客户端发送的ACK包,则结束TCP连接。

    然而如果浏览器或者服务器在其头信息加入了这行代码:

    Connection:keep-alive

   TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。


4. 一台主机上出现大量的TIME_WAIT是什么原因?应该如何处理?

    答:TIME_WAIT是主动关闭方出现的,一台主机出现大量的TIME_WAIT证明这台主机上发起大量的主动关闭连接。常见于一些爬虫服务器。这时候我们应该调整TIME_WAIT的等待时间,或者开启套接字地址重用选项。

5. 一台主机上出现大量的CLOSE_WAIT是什么原因?应该如何处理?

    答:CLOSE_WAIT是被动关闭方收到FIN请求进行回复之后的状态,等待上层程序进一步处理,若出现大量CLOSE_WAIT,有可能是被动关闭方主机程序中忘了最后一步断开连接后调用close释放资源。这是一个 BUG,只需要加上对应的 close 即可解决问题。

6. TCP连接管理中的保活机制

    答:TCP通信中,若两端长时间没有数据往来,则这时候每隔一段时间,服务端会向客户端发送一个保活探测数据报,要求客户端进行回复。若连续多次没有收到响应,就认为连接已经断开。长时间默认为7200s,每隔一段时间默认为75s,连续多次无响应默认为9次。这些数据都可以在套接字中修改,接口:Setsockopt。


作者:justloving

来源:https://www.cnblogs.com/justloving/p/16660957.html


点击关注,带你了解更多

展开阅读全文

页面更新:2024-05-01

标签:报文   队列   服务器端   服务端   全过程   客户端   浏览器   状态   服务器   数据   资源

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top