fe_interview
fe_interview copied to clipboard
讲一下TCP三次握手、四次挥手过程及原理
什么是TCP
?
TCP
提供面向有连接的通信传输,面向有连接是指在传送数据之前必须先建立连接,数据传送完成后要释放连接。
无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP
协议中,TCP
协议提供可靠的连接服务,连接是通过三次握手
进行初始化的。
同时由于TCP
协议是一种面向连接的、可靠的、基于字节流的运输层通信协议,TCP
是全双工模式
,所以需要四次挥手
关闭连接。
TCP 包头格式
图片来源网络
TCP
首部承载这TCP
协议需要的各项信息,下面我们来分析一下:
-
TCP
端口号
TCP
的连接是需要四个要素确定唯一一个连接:(源IP
,源端口号)+ (目的IP
,目的端口号)
所以TCP
首部预留了两个 16 位作为端口号的存储,而IP
地址由上一层IP
协议负责传递。
源端口号和目地端口各占 16 位两个字节,也就是端口的范围是2^16=65535
-
TCP
的序号和确认号- 32 位序号
seq
Sequence number
缩写seq
,TCP
通信过程中某一个传输方向上的字节流的每个字节的序号,通过这个来确认发送的数据有序,比如现在序列号为 1000,发送了 1000,下一个序列号就是 2000。 - 32 位确认号
ack
Acknowledge number
缩写ack
,TCP
对上一次seq
序号做出的确认号,用来响应TCP
报文段,给收到的TCP
报文段的序号seq
加 1。
- 32 位序号
-
TCP
的标志位 每个TCP
段都有一个目的,这是借助于 TCP 标志位选项来确定的,允许发送方或接收方指定哪些标志应该被使用,以便段被另一端正确处理。用的最广泛的标志是
SYN
,ACK
和FIN
,用于建立连接,确认成功的段传输,最后终止连接。-
SYN
:简写为 S,同步标志位,用于建立会话连接,同步序列号; -
ACK
: 简写为.,确认标志位,对已接收的数据包进行确认; -
FIN
: 简写为 F,完成标志位,表示我已经没有数据要发送了,即将关闭连接; -
PSH
:简写为 P,推送标志位,表示该数据包被对方接收后应立即交给上层应用,而不在缓冲区排队; -
RST
:简写为 R,重置标志位,用于连接复位、拒绝错误和非法的数据包; -
URG
:简写为 U,紧急标志位,表示数据包的紧急指针域有效,用来保证连接不被阻断,并督促中间设备尽快处理;
-
TCP 三次握手和四次挥手
三次握手
图片来源网络
- 第一次握手:客户端将
TCP
报文标志位SYN
置为 1,随机产生一个序号值 seq=J
,保存在TCP
首部的序列号(Sequence Number
)字段里,指明客户端打算连接的服务器的端口,并将该数据包发送给服务器端,发送完毕后,客户端进入SYN_SENT
状态,等待服务器端确认。 - 第二次握手:服务器端收到数据包后由标志位
SYN=1
知道客户端请求建立连接,服务器端将TCP
报文标志位SYN
和ACK
都置为 1,ack=J+1
,随机产生一个序号值seq=K
,并将该数据包发送给客户端以确认连接请求,服务器端进入SYN_RCVD
状态。 - 第三次握手:客户端收到确认后,检查
ack
是否为J+1
,ACK
是否为 1,如果正确则将标志位ACK
置为 1,ack=K+1
,并将该数据包发送给服务器端,服务器端检查ack
是否为K+1
,ACK
是否为 1,如果正确则连接建立成功,客户端和服务器端进入ESTABLISHED
状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。
注意:我们上面写的 ack 和 ACK,不是同一个概念:
- 小写的
ack
代表的是头部的确认号Acknowledge number
, 缩写ack
,是对上一个包的序号进行确认的号,ack=seq+1
。 - 大写的
ACK
,则是我们上面说的TCP
首部的标志位,用于标志的TCP
包是否对上一个包进行了确认操作,如果确认了,则把ACK
标志位设置成 1。
四次挥手
- 第一次挥手。客户端发起挥手请求,向服务端发送标志位是
FIN
报文段,设置序列号seq
- 第二次挥手。服务端收到了客户端发送的
FIN
报文段,向客户端返回一个标志位是ACK
的报文段,ack
设为seq
加 1 - 第三次挥手。服务端向客户端发送标志位是
FIN
的报文段,请求关闭连接,设置序列号seq
- 第四次挥手。客户端收到服务端发送的
FIN
报文段,向服务端发送标志位是ACK
的报文段,ack
设为seq
加 1。服务端收到客户端的ACK
报文段以后,就关闭连接。此时,客户端等待2MSL
的时间后依然没有收到回复,则证明服务端已正常关闭,那么客户端也可以关闭连接了。
为什么连接的时候是三次握手,关闭的时候却是四次握手?
建立连接时因为当 Server
端收到 Client
端的 SYN
连接请求报文后,可以直接发送 SYN+ACK
报文。其中 ACK
报文是用来应答的,SYN
报文是用来同步的。所以建立连接只需要三次握手。
由于 TCP
协议是一种面向连接的、可靠的、基于字节流的运输层通信协议,TCP
是全双工模式
。
这就意味着,关闭连接时,当 Client
端发出 FIN
报文段时,只是表示 Client
端告诉 Server
端数据已经发送完毕了。当 Server
端收到 FIN
报文并返回 ACK
报文段,表示它已经知道 Client
端没有数据发送了,但是 Server
端还是可以发送数据到 Client
端的,所以 Server
很可能并不会立即关闭 SOCKET
,直到 Server
端把数据也发送完毕。
当 Server
端也发送了 FIN
报文段时,这个时候就表示 Server
端也没有数据要发送了,就会告诉 Client
端,我也没有数据要发送了,之后彼此就会愉快的中断这次 TCP
连接。