1. 完整的http事务
  2. DNS解析流程
  3. TCP的三次握手和四次挥手
  4. 可以二次握手吗
  5. 什么是SYN洪泛攻击
  6. 四次挥手服务端主动断开连接会怎么样
  7. timewait大量出现
  8. 为什么在timewait状态必须等待2MSL时间
  9. 为什么握手是三次,而挥手是四次
  10. 如果是https呢

大致流程

  • URL解析
  • DNS解析
  • TCP连接
  • 服务器处理请求
  • 客户端接受HTTP报文响应
  • 渲染页面

    URL解析

    地址解析:首先判断你输入的是一个合法的 URL 还是一个待搜索的关键词,并且根据你输入的内容进行自动完成字符编码等操作。这些步骤由浏览器来完成
    image.png

  • if-Modified-Since 通常会与 If-None-Match 搭配使用,If-Modified-Since 用于确认代理或客户端拥有的本地资源的有效性。获取资源的更新日期时间,可通过确认首部字段 Last-Modified 来确定。

    如果在 Last-Modified 之后更新了服务器资源,那么服务器会响应 200,如果在 Last-Modified 之后没有更新过资源,则返回 304。

  • Expires 实体主体过期的日期时间

  • Cache Control 缓存控制的行为

    DNS解析

    image.png
  1. 浏览器缓存:先检查是否在缓存中,没有则调用系统库函数进行查询。
  2. 操作系统缓存:操作系统也有自己的 DNS 缓存,但在这之前,会向检查域名是否存在本地的 Hosts 文件里,没有则向 DNS 服务器发送查询请求。
  3. 路由器缓存。
  4. ISP DNS 缓存:ISP DNS 就是在客户端电脑上设置的首选 DNS 服务器,它们在大多数情况下都会有缓存。

    根域名服务器

    在前面所有步骤没有缓存的情况下,本地 DNS 服务器会将请求转发到互联网上的根域
    image.png

  5. 递归方式:一路查下去中间不返回,得到最终结果才返回信息(浏览器到本地 DNS 服务器的过程)

  6. 迭代方式,就是本地 DNS 服务器到根域名服务器查询的方式。网络上的DNS服务器只会告诉你去找谁找dns
  7. dns劫持:错误域名解析
  8. dns-prefetch 前端使用dns-prefetch预解析,加快访问速度

    TCP连接建立与断开

    TCP/IP 分为四层,在发送数据时,每层都要对数据进行封装和拆解不不同的头:
    image.png

  9. 应用层:发送http请求

浏览器从地址栏得到服务器 IP,接着构造一个 HTTP 报文,其中包括:

  • 请求报头(Request Header):请求方法、目标地址、遵循的协议等
  • 请求主体,请求参数,比如 body 里面的参数
  1. 传输层:TCP传输报文

传输层会发起一条到达服务器的 TCP 连接,为了方便传输,会对数据进行分割(以报文段为单位),并标记编号,方便服务器接受时能够准确地还原报文信息。在建立连接前,会先进行 TCP 三次握手。

  1. 网络层:IP协议查询MAC地址

将数据段打包,加入源及目标的 IP 地址,并且负责寻找传输路线。判断目标地址是否与当前地址处于同一网络中,是的话直接根据 Mac 地址发送,否则使用路由表查找下一个地址,以及使用 ARP 协议查询它的 Mac 地址。

  1. 链路层:以太网协议

根据以太网协议将数据分为以“帧”为单位的数据包,每一帧分为两个部分:

  • 标头:数据包的发送者、接受者、数据类型
  • 数据:数据包具体内容

主要的请求过程:

  1. 浏览器从地址栏中获取服务器的 IP 和端口号;
  2. 浏览器与服务器之间通过 TCP 三次握手建立连接;
  3. 浏览器向服务器发送报文;
  4. 服务器接收报文处理,同时将响应报文发给浏览器;
  5. 浏览器解析报文,渲染输出到页面;

    三次握手

    在传输层传输数据之前需要建立连接,也就是三次握手创建可靠连接。
    image.png
    首先建立链接前需要 Server 端先监听端口,因此 Server 端建立链接前的初始状态就是 LISTEN 状态,这时 Client 端准备建立链接,先发送一个 SYN 同步包,发送完同步包后,Client 端的链接状态变成了 SYN_SENT 状态。Server 端收到 SYN 后,同意建立链接,会向 Client 端回复一个 ACK。
    由于 TCP 是双工传输,Server 端也会同时向 Client 端发送一个 SYN,申请 Server 向 Client 方向建立链接。发送完 ACK 和 SYN 后,Server 端的链接状态就变成了 SYN_RCVD。
    Client 收到 Server 的 ACK 后,Client 端的链接状态就变成了 ESTABLISHED 状态,同时,Client 向 Server 端发送 ACK,回复 Server 端的 SYN 请求。
    Server 端收到 Client 端的 ACK 后,Server 端的链接状态也就变成了的 ESTABLISHED 状态,此时建连完成,双方随时可以进行数据传输。

    建立双向的连接,不只是一端到另一端。 SYN洪水攻击: Server端收到Client端的SYN请求后,发送了SYN和ACK,但client不进行回复,导致Server端大量链接处于SYN_RCVD状态,从而影响其他正常请求的建立。可以设置**tcp_synack_retries = 0**加快半连接的回收速度,或者调大tcp_max_syn_backlog来应对少量的SYN洪水攻击

可以两次挥手吗?
主要为了防止已失效的连接请求报文段突然又传送到了B,因而产生错误。如A发出连接请求,但因连接请求报文丢失而未收到确认,于是A再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,A工发出了两个连接请求报文段,其中第一个丢失,第二个到达了B,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达B,此时B误认为A又发出一次新的连接请求,于是就向A发出确认报文段,同意建立连接不采用三次握手,只要B发出确认,就建立新的连接了此时A不理睬B的确认且不发送数据,则B一直等待A发送数据,浪费资源

四次挥手

一次完整的http事务 - 图6
客户端:主动去断开连接

  • FIN_WAIT_1 - 客户端发送了关闭连接的 FIN 报文后,等待服务端回复 ACK 确认。
  • FIN_WAIT_2 - 表示我方已关闭连接,正在等待服务端关闭。客户端发了关闭连接的 FIN 报文后,服务器发回 ACK 应答,但是没进行关闭,就会处于这种状态。
  • TIME_WAIT - 双方都正常关闭连接后,客户端会维持 TIME_WAIT 一段时间,以确保最后一个 ACK 能成功发送到服务器端。停留时长为 2 倍的 MSL (报文最大生存时间),Linux 下大约是 60 秒。所以在一个频繁建立短连接的服务器上通常可以看到成千上万的 TIME_WAIT 连接。

服务端:被动断开连接

  • CLOSE_WAIT - 表示客户端已经关闭连接,但是本地还没关闭,正在等待本地关闭。有时客户端程序已经退出了,但服务端程序由于异常或 BUG 没有调用 close()函数对连接进行关闭,那在服务器这个连接就会一直处于 CLOSE_WAIT 状态,而在客户机已经不存在这个连接了。
  • LAST_ACK - 表示正在等待客户端对服务端的关闭请求进行最终确认。

    msl: 报文最大生存时间

    服务端主动断开:如果服务端主动关闭连接,那么服务端就会先发送fin,最后要有个2MSL的**TIME-WAIT**。如果服务端在一段时间内主动关闭的连接比较多,则服务端会有大量的**TIME-WAIT**状态的连接要等2MSL时间,在Windows下默认为4分钟。

TIME_WAIT状态存在的意义

  1. 可靠的终止TCP链接

这样可让TCP再次发送最后的ACK以防这个ACK丢失

  1. 保证让迟来的TCP报文段有足够的时间被识别并丢弃

每个具体TCP实现必须选择一个报文段最大生存时间MSL。它是任何报文段被丢弃前在网络内的最长时间。
断链问题:
大量 Socket 处在 TIME_WAIT 或者 CLOSE_WAIT 状态的问题。一般开启 tcp_tw_reusetcp_tw_recycle能够加快 TIME-WAIT 的 Sockets 回收;而大量 CLOSE_WAIT 可能是被动关闭的一方存在代码 bug,没有正确关闭链接导致的。

等待2MSL时间

  1. 保证A发送的最后一个ACK报文段能够到达B(最后一个ack包可能丢失)
  2. 防止已失效的连接请求报文段出现在本连接中。

    三次握手而四次挥手的必要

    因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了我才能发送FIN报文,因此不能一起发送。故需要四步握手。

    服务器处理请求并相应HTTP报文

    http报文如下
    image.png
    比图 TCP 报文,它在实际要传输的数据之前附加了一个 20 字节的头部数据,存储 TCP 协议必须的额外信息,例如发送方的端口号、接收方的端口号、包序号、标志位等等。

HTTP 协议规定报文必须包含 Header,而且之后必须有一个 “空行”,也就是“CRLF”,十六进制的“0D0A”,可以没有 “body”
image.png

浏览器接收响应并渲染数据

浏览器接收到来自服务器的响应资源后,会对资源进行分析。首先查看 Response header,根据不同状态码做不同的事(比如上面提到的重定向)。如果响应资源进行了压缩(比如 gzip),还需要进行解压。然后,对响应资源做缓存。接下来,根据响应资源里的 MIME类型去解析响应内容(比如 HTML、Image 各有不同的解析方式)。
image.png

HTTPS

在tcp建立连接后多了SSL/TLS的互信确立,并以密文传递信息。

知识链接

  1. 输入网址按回车,到底发生了什么
  2. 一次完整的HTTP事务是怎样一个过程?