过程
- DNS解析
- TCP连接
- 发送HTTP请求
- 服务器处理请求并返回HTTP报文
- 浏览器解析和渲染页面
- 连接结束
DNS解析
DNS解析实际上就是在网络上寻找资源的过程;
我们输入网址www.baido.com后,这个网址实际上并不是百度真实地址,互联网中每一台机器都有唯一标识的IP地址。但是IP地址并不好记,所以需要一个网址和IP地址之间的转换,这个过程也就是DNS解析。
过程
DNS解析过程实际上是一个递归过程:
本地域名服务器 -> 根域名服务器 -> COM域名服务器 -> baidu.com域名服务器
对应
. -> .com -> baidu.com. -> www.baidu.com.
中间任何一个环节找到了IP地址,就结束查找,把IP地址返回给client端
DNS优化
从上面的查找过程可以看到,如果每次都查找,会是一个繁琐的过程。每个过程有一定的消耗和时间等待,因此我们需要想一个解决方法!
DNS缓存
DNS存在多级缓存,从离浏览器距离排序:
- 浏览器缓存
- 系统缓存
- 路由器缓存
- IPS服务器缓存
- 根域名服务器缓存
- 顶级域名服务器缓存
- 主域名服务器缓存
DNS负载均衡
DNS可以返回一个合适的机器的IP给用户,例如可以根据每台机器的负载量,该服务器离用户地理位置的距离等;这个过程叫做DNS负载均衡
发送TCP连接
TCP提供的是面向连接、可靠的字节流传输;过程涉及到三次握手,四次挥手。
TCP数据格式
字段分析
-
序号(Seq):是TCP可靠传输的关键部分。序号是该报文段发送的数据组的第一个字节的序号。在TCP传送的流中,每一个字节都有一个序号。比如一个报文段的序号为300,报文段数据部分共有100字节,则下一个报文段的序号为400。所以序号确保了TCP传输的有序性。
-
确认号(ack):即ACK,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志为1时才有效。比如建立连接时,SYN报文的ACK标志位为0。
这里有一个考点:
问:电脑系统有多少个端口
答: 2^16 - 1
从上面TCP数据格式可以看出:有16位端口号
- SYN:TCP/IP建立连接数使用的握手信号
- Seq:序列号
- ack:确认序列号
- FIN:TCP/IP断开连接时使用的挥手信号
三次握手
- 第一次握手
客户端发送
SYN包(Seq = x)到服务器,进入SYN_SEND状态,等待服务器确认
注:SYN是TCP/IP建立连接时使用的握手信号
-
第二次握手 服务器接收到SYN包,需要确认客户的SYN(ack = x + 1),同时自己也发送一个SYN包(Seq = y),既
SYN + ACK包,此时服务器进入SYN_RECV状态 -
第三次握手 客户端收到服务器的SYN + ACK包,向服务器发送确认包
ACK(ack = y + 1),发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
三次握手完毕后,客户端和服务端才正式开始传送数据。理想状态下,TCP连接一旦建立,TCP连接都会一直保持下去。
因为TCP是一个面向连接的协议,所以需要在数据传输前切点好客户端(A)和服务端(B)都可以正常的接受和发送字节数据
也就是A需要知道:1.A发送;2.A接收;3.B发送;4.B接收 是正常的
同时B也需要知道:1.A发送;2.A接收;3.B发送;4.B接收 是正常的
在第一次握手后:
A知道:1.A发送;2.A接收;3.B发送;4.B接收
B知道:1.A发送;2.A接收;3.B发送;4.B接收
在第二次握手后:
A知道:1.A发送;2.A接收;3.B发送;4.B接收
B知道:1.A发送;2.A接收;3.B发送;4.B接收
在第三次握手后:
A知道:1.A发送;2.A接收;3.B发送;4.B接收
B知道:1.A发送;2.A接收;3.B发送;4.B接收
所以三次握手后,双方都可以确定连接是正常的,可以开始发送数据
四次挥手
这里假设客户端是主动关闭,服务器是被动关闭
- 第一次挥手
客户端发送一个FIN,用来关闭客户端到服务器的数据传递,也就是告诉服务器:客户端不会再给服务端发消息了(如果在fin包之前发送的数据,如果没有得到对应的ACK确认报文,客户端依然会重新发送数据)。
但是客户端还是可以接受数据。FIN = 1,其序列号为Seq = u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入 FIN-WAIT-1(终止等待1)状态。TCP规定:FIN报文段即使不携带数据也会消耗一个序号。
- 第二次挥手
服务器接受到FIN包后,发送一个ACK给客户端并带上自己的序号Seq(确认序号为收到序号 + 1:u + 1)。
此时服务器进入了CLOSE-WAIT(关闭等待)状态。此时客户端向服务器发送消息的方向释放了,这个时候处于半关闭状态。但是如果服务端发送数据,客户端依然可以接受。
客户端进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(也就是第三次挥手)
- 第三次挥手
服务器发送FIN,用来关闭服务器到客户端的数据发送,也就是告诉客户端,我的数据也发送完了。不会再给你发数据了。
由于在半关闭状态,服务器可能又发送了一些数据,假设此时的seq=w,此时服务器进入LAST-ACK(最后确认)状态,等待客户端的确认
- 第四次挥手
客户端收到FIN后,发送一个ACK给被动关闭方,seq为收到的序列号 + 1.此时客户端进入了TIME-WAIT(时间等待)状态。
注意此时TCP连接还没有释放,必须经过 2MSL(最长报文段寿命)的时间后,当客户端撤销对应的TCP后,才会进入CLOSE状态。
服务器收到客户端的确认后,立刻进入CLOSED状态
为什么客户端最后要等待2MSL?
-
保证客户端最后一次发送的ACK会被服务端接受到,因为如果服务端发送完FIN + ACK 后,等待客户端相应,如果客户端没有回应(实际上服务端发送了ACK,但是报文丢失),服务器端会觉得应该是我的发送请求没有接受到,于是服务端会重新发送,而客户端就能在2MSL时间段内收到这个重传的报文。接着回应报文,并重启2MSL计时器
-
为了防止“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间内,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。