- 完整的http事务
- DNS解析流程
- TCP的三次握手和四次挥手
- 可以二次握手吗
- 什么是SYN洪泛攻击
- 四次挥手服务端主动断开连接会怎么样
- timewait大量出现
- 为什么在timewait状态必须等待2MSL时间
- 为什么握手是三次,而挥手是四次
- 如果是https呢
大致流程
- URL解析
- DNS解析
- TCP连接
- 服务器处理请求
- 客户端接受HTTP报文响应
-
URL解析
地址解析:首先判断你输入的是一个合法的 URL 还是一个待搜索的关键词,并且根据你输入的内容进行自动完成、字符编码等操作。这些步骤由浏览器来完成

if-Modified-Since通常会与If-None-Match搭配使用,If-Modified-Since用于确认代理或客户端拥有的本地资源的有效性。获取资源的更新日期时间,可通过确认首部字段Last-Modified来确定。如果在
Last-Modified之后更新了服务器资源,那么服务器会响应 200,如果在Last-Modified之后没有更新过资源,则返回 304。Expires实体主体过期的日期时间Cache Control缓存控制的行为DNS解析

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

递归方式:一路查下去中间不返回,得到最终结果才返回信息(浏览器到本地 DNS 服务器的过程)
- 迭代方式,就是本地 DNS 服务器到根域名服务器查询的方式。网络上的DNS服务器只会告诉你去找谁找dns
- dns劫持:错误域名解析
dns-prefetch 前端使用dns-prefetch预解析,加快访问速度
TCP连接建立与断开
TCP/IP 分为四层,在发送数据时,每层都要对数据进行封装和拆解不不同的头:

应用层:发送http请求
浏览器从地址栏得到服务器 IP,接着构造一个 HTTP 报文,其中包括:
- 请求报头(Request Header):请求方法、目标地址、遵循的协议等
- 请求主体,请求参数,比如 body 里面的参数
- 传输层:TCP传输报文
传输层会发起一条到达服务器的 TCP 连接,为了方便传输,会对数据进行分割(以报文段为单位),并标记编号,方便服务器接受时能够准确地还原报文信息。在建立连接前,会先进行 TCP 三次握手。
- 网络层:IP协议查询MAC地址
将数据段打包,加入源及目标的 IP 地址,并且负责寻找传输路线。判断目标地址是否与当前地址处于同一网络中,是的话直接根据 Mac 地址发送,否则使用路由表查找下一个地址,以及使用 ARP 协议查询它的 Mac 地址。
- 链路层:以太网协议
根据以太网协议将数据分为以“帧”为单位的数据包,每一帧分为两个部分:
- 标头:数据包的发送者、接受者、数据类型
- 数据:数据包具体内容
主要的请求过程:
- 浏览器从地址栏中获取服务器的 IP 和端口号;
- 浏览器与服务器之间通过 TCP 三次握手建立连接;
- 浏览器向服务器发送报文;
- 服务器接收报文处理,同时将响应报文发给浏览器;
- 浏览器解析报文,渲染输出到页面;
三次握手
在传输层传输数据之前需要建立连接,也就是三次握手创建可靠连接。
首先建立链接前需要 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发送数据,浪费资源。
四次挥手

客户端:主动去断开连接
- 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状态存在的意义
- 可靠的终止TCP链接
这样可让TCP再次发送最后的ACK以防这个ACK丢失
- 保证让迟来的TCP报文段有足够的时间被识别并丢弃
每个具体TCP实现必须选择一个报文段最大生存时间MSL。它是任何报文段被丢弃前在网络内的最长时间。
断链问题:
大量 Socket 处在 TIME_WAIT 或者 CLOSE_WAIT 状态的问题。一般开启 tcp_tw_reuse和 tcp_tw_recycle能够加快 TIME-WAIT 的 Sockets 回收;而大量 CLOSE_WAIT 可能是被动关闭的一方存在代码 bug,没有正确关闭链接导致的。
等待2MSL时间
- 保证A发送的最后一个ACK报文段能够到达B(最后一个ack包可能丢失)
- 防止已失效的连接请求报文段出现在本连接中。
三次握手而四次挥手的必要
因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。服务器处理请求并相应HTTP报文
http报文如下
比图 TCP 报文,它在实际要传输的数据之前附加了一个 20 字节的头部数据,存储 TCP 协议必须的额外信息,例如发送方的端口号、接收方的端口号、包序号、标志位等等。
HTTP 协议规定报文必须包含 Header,而且之后必须有一个 “空行”,也就是“CRLF”,十六进制的“0D0A”,可以没有 “body”。
浏览器接收响应并渲染数据
浏览器接收到来自服务器的响应资源后,会对资源进行分析。首先查看 Response header,根据不同状态码做不同的事(比如上面提到的重定向)。如果响应资源进行了压缩(比如 gzip),还需要进行解压。然后,对响应资源做缓存。接下来,根据响应资源里的 MIME类型去解析响应内容(比如 HTML、Image 各有不同的解析方式)。
HTTPS
在tcp建立连接后多了SSL/TLS的互信确立,并以密文传递信息。
