前端面试知识_TCP
前言
仅用于个人学习总结,有不足还请指出。
一、概念
1.TCP:传输控制协议
报头格式:
- 源端口号/目的端口号: 表示数据从哪个进程来, 到哪个进程去.
- 32位序号:
- 4位首部长度: 表示该tcp报头有多少个4字节(32个bit)
- 6位保留: 顾名思义, 先保留着, 以防万一
- 6位标志位
URG: 标识紧急指针是否有效
ACK: 标识确认序号是否有效
PSH: 用来提示接收端应用程序立刻将数据从tcp缓冲区读走
RST: 要求重新建立连接. 我们把含有RST标识的报文称为复位报文段
SYN: 请求建立连接. 我们把含有SYN标识的报文称为同步报文段
FIN: 通知对端, 本端即将关闭. 我们把含有FIN标识的报文称为结束报文段
- 16位窗口大小:
- 16位检验和: 由发送端填充, 检验形式有CRC校验等. 如果接收端校验不通过, 则认为数据有问题. 此处的校验和不光包含TCP首部, 也包含TCP数据部分.
- 16位紧急指针: 用来标识哪部分数据是紧急数据.
- 选项和数据暂时忽略
2.TCP的封装和解封过程:
3.TCP特点
- TCP 是
面向连接
的运输层协议。应用程序在使用 TCP 协议之前,必须先建立 TCP 连接。在传送数据完毕后,必须释放已经建立的 TCP 连接
每一条 TCP 连接唯一地被通信两端的两个端点(即两个socket = ip:port)所确定
故:同一个 IP 地址可以有多个不同的 TCP 连接,而同一个端口号也可以出现在多个不同的 TCP 连接中 - 每一条 TCP 连接只能有两个端点,每一条 TCP 连接只能是
点对点
的(一对一) - TCP 提供可靠交付的服务。通过 TCP 连接传送的数据,
无差错、不丢失、不重复,并且按序到达
- TCP 提供
全双工通信
。TCP 允许通信双方的应用进程在任何时候都能发送数据。TCP 连接的两端都有发送缓存和接受缓存,用来临时存放双向通信的数据 面向字节流
,TCP 中的“流”指的是流入到进程或从进程流出的字节序列
二、TCP的三次握手&四次挥手
正常情况下,tcp要经过三次握手建立连接,四次挥手断开连接
1.三次握手
- 第一次握手:建立连接时,客户端发送
syn包(syn=1)
并请求到服务器,这个包中包含客户端起始序列号(Seq=client_isn)
。然后进入SYN_SENT状态,等待服务器确认。 - 第二次握手:服务器收到syn包并确认客户的SYN,同时也发送
SYN+ACK包(在 TCP 标头中SYN和ACK位字段都为 1 的 TCP/IP 数据包)
这个包中包含服务端起始序列号Seq=server_isn
,以及确认号ack= client_isn+1
表示已经收到client_isn 并请求client_isn+1。此时服务器进入SYN_RECV状态; - 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送
确认包ACK(ACK=server_isn+1,含义与第二步ACK相同)
,此包包含SYN+ACK包所请求的clinet_isn+1(即seq = client_isn+1)
,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
为什么不用两次握手?
主要是为了防止已经失效的连接请求报文(滞留时间过长)突然又传送到了服务器,从而产生错误。
因为如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。
2.四次挥手
在断开连接之前客户端和服务器都处于ESTABLISHED状态,双方都可以主动断开连接,以客户端主动断开连接为优。
-
第一次挥手:客户端打算断开连接,向服务器发送
FIN报文(FIN标记位被设置为1)
,FIN报文中会指定一个序列号,之后客户端进入FIN_WAIT_1状态。也就是客户端发出连接释放报文段(FIN报文),指定序列号seq = u,主动关闭TCP连接,等待服务器的确认。
-
第二次挥手:服务器收到连接释放报文段(FIN报文)后,就向客户端发送
ACK应答报文
,以客户端的FIN报文的序列号 seq+1 作为ACK应答报文段的确认序列号ack = seq+1 = u + 1。接着服务器进入CLOSE_WAIT(等待关闭)状态,此时的TCP处于半关闭状态(下面会说什么是半关闭状态),客户端到服务器的连接释放。客户端收到来自服务器的ACK应答报文段后,进入FIN_WAIT_2状态。
-
第三次握手:服务器也打算断开连接,向客户端发送连接释放
(FIN)报文段
,之后服务器进入LASK_ACK(最后确认)状态,等待客户端的确认。服务器的连接释放(FIN)报文段的FIN=1,ACK=1,序列号seq=m,确认序列号ack=u+1。
-
第四次握手:客户端收到来自服务器的连接释放(FIN)报文段后,会向服务器发送一个
ACK应答报文段
,以连接释放(FIN)报文段的确认序号 ack 作为ACK应答报文段的序列号 seq,以连接释放(FIN)报文段的序列号 seq+1作为确认序号ack。之后客户端进入
TIME_WAIT(时间等待)状态
,服务器收到ACK应答报文段后,服务器就进入CLOSE(关闭)状态
,到此服务器的连接已经完成关闭。
客户端处于TIME_WAIT状态时,此时的TCP还未释放掉
,需要等待2MSL
后,客户端才进入CLOSE状态
。
为什么要四次挥手?
这是由于TCP的半关闭(half-close)造成的
:TCP提供了连接的一方在结束它的发送后还能接受来自另一端数据的能力(但无法发送数据)。
当连接处于半关闭状态时,TCP是允许单向传输数据的,也就是说服务器此时仍然可以向客户端发送数据,等服务器不再发送数据时,才会发送FIN报文段,同意现在关闭连接。这是由于TCP双向通道互相独立造成的,所以必须经历四次挥手才能关闭连接。
为什么TIME_WAIT等待时间是2MSL?
MSL(Maximum Segment LifeTime)
是报文最大生成时间,它是任何报文在网络上存在的最长时间
,超过这个时间的报文将被丢弃。
- 2MSL时间是从客户端接收到FIN后发送ACK开始计时的。如果在这个时间段内,服务器没有收到ACK应答报文段,会重发FIN报文段,如果客户端收到了FIN报文段,那么2MSL的时间将会被重置。如果在2MSL时间段内,没有收到任何数据报,客户端则会进入CLOSE状态。
- 保证客户端最后发送的ACK能够到达服务器,帮助其正常关闭。
由于这个ACK报文段可能会丢失,使得处于LAST_ACK状态的服务器得不到对已发送FIN报文段的确认,从而会触发超时重传。服务器会重发FIN报文段,客户端能保证在2MSL时间内收到来自服务器的重传FIN报文段,从而客户端重新发送ACK应答报文段,并重置2MSL计数。
- 防止已失效的连接请求报文段出现在本连接中。
三、其他
1.TCP和UDP的区别
- TCP是面向
链接
的,而UDP是面向无连接
的。 - TCP仅支持
单播
传输,UDP 提供了单播,多播,广播
的功能。 - TCP的三次握手保证了连接的
可靠
; UDP是无连接的、不可靠
的一种数据传输协议,首先不可靠性体现在无连接上,通信都不需要建立连接,对接收到的数据也不发送确认信号,发送端不知道数据是否会正确接收。 UDP的头部开销比TCP的更小
,数据传输速率更高,实时性更好。
2.TCP如何保证可靠传播
对字节流分段并进行编号然后通过 ACK 回复
和超时重发
这两个机制来保证。
- 为了保证数据包的可靠传递,发送方必须把已发送的数据包保留在缓冲区,并为每个已发送的数据包启动一个超时定时器;
- 如在定时器超时之前收到了对方发来的应答信息(可能是对本包的应答,也可以是对本包后续包的应答),则释放该数据包占用的缓冲区否则,重传该数据包,直到收到应答或重传次数超过规定的最大次数为止。
- 接收方收到数据包后,先进行CRC校验,如果正确则把数据交给上层协议,然后给发送方发送一个累计应答包,表明该数据已收到,如果接收方正好也有数据要发给发送方,应答包也可方在数据包中捎带过去。
总结
以上就是关于HTTP知识点的一些总结,如有不足还请指出!