tcp 链接的建立和断开
面试总是不免被问到 简述 tcp 三次握手 四次挥手的问题。
这个问题困扰我许久,因为我一直不能解释清楚为什么 握手需要三次 挥手需要四次 为什么不是五次或者两次 多一次少一次不行吗?
三次握手的目的
tcp 协议是用于两台机器在网络上通讯用的。
那么这涉及到一个问题:怎么保证在数据传输之前两台机器都有通讯能力
。
对话的必要条件
- 有AB
两个对象
- AB都能
接收
和发送
消息
以上的的条件需要 A 和 B 都知道双方都拥有这个能力。(达成共识)
为什么是三次
我刚才提到机器通讯前需要双方都在线并且都拥有通讯能力
,那么我们看下最少需要多少步能够满足对话的必要条件。
第一步:
A 向 B 在一定时间范围内发送[1]
尝试想要建立链接的消息 (如果成功证明 A 能够发消息)
第二步: (B 接受到 A 的消息)
B 向 A 发送[2]
收到了 A 的消息的消息 (已经证明 A 能够发送消息 B 能够接收消息) (未知的是 A 能不能收到 B 的消息,以及 B 能不能成功的发消息)
第三步: (A 接受到 B 的消息)
停止第一步的行为。
此时 A 已经知道了 AB 都具有收发消息的能力。
但是 B 还不知道 A 能不能接收到消息。
所以这个时候需要 A 发送[3]
一条消息告诉 B 。
如果 B 收到了消息说明双方都具备的完成一次对话的基本条件,tcp链接建立完成。
四次挥手
四次挥手的目的是为了达到完成一次通讯后能够关闭无用链接释放掉服务器资源来做其他的事。
由于 tcp 是一种全双工通讯协议。
所以达到目的的标志是
AB 双方都关闭了自己的 接受数据
的接口 和 发送数据
的接口。
我们来看下最少需要多少步:
1、A(主动方)发起[1]
断开链接的请求告诉A所有数据发送完毕可以关闭接收数据的接口 (只是说明A将要关闭发送接口,此时A正常接收数据)
2、B(被动方)接收到请求关闭接收数据的接口
向 A 发送[2]
确认关闭接收数据的接口的消息,叫A不要再次发送关闭链接的请求了。
A 收到 B 的确认消息后关闭了发送接口,等待 B 将所有的数据传输完毕后关闭接口的消息。
3、B 如果没有数据传输给 A 了会发送[3]
一条关闭发送接口的消息给 A 让 A 关闭自己的就收数据的接口。
4、A 收到 B 的消息后会关闭自己的接收数据接口,并且发送[4]
一条确认消息告诉 B 不要再次发送关闭接口的通知了。
如图:
为什么建立连接是三次握手,而关闭连接却是四次挥手呢?这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。
(完)