TCP为什么是三次握手四次hui'shou
运维少年 运维少年
TCP简介
TCP提供一种面向连接的、可靠的字节流服务。其中,面向连接意味着两个使用TCP的应用(通常是一个客户和一个服务器)在彼此交换数据之前必须先建立一个TCP连接。在一个TCP连接中,仅有两方进行彼此通信;而字节流服务意味着两个应用程序通过TCP链接交换8bit字节构成的字节流,TCP不在字节流中插入记录标识符。
三次握手
TCP通过三次握手建立连接关系,建立连接关系之后再进行数据交互。
三次握手如何进行?
- 第一次握手:Client向Server发送请求报文,SYN=1,ACK=0,随机产生一个值seq=x,Client进入SYN_SENT状态,等待Server确认。
-
第二次握手:Server收到请求报文后,如果同意建立连接,则向Client发送连接确认报文,SYN=1,ACK=1,ack=x+1,并随机产生一个值seq=y,Server进入SYN_RCVD状态。
- 第三次握手:Client收到确认后,检查ack是否为x+1,ACK是否为1,如果正确则向Server发送确认报文,ACK=1,ack=y+1,seq=x+1,Server检查ack是否为x+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
为什么要三次握手,两次不可以吗?
试想一下,A第一次发送请求连接,但是在网络某节点滞留了,A超时重传,然后这一次一切正常,A跟B就愉快地进行数据传输了。等到连接释放了以后,那个迷失了的连接请求突然到了B那,如果是两次握手的话,B发送确认,它们就算是建立起了连接了。事实上A并不会理会这个确认,因为我压根没有要传数据啊。但是B却傻傻地以为有数据要来,苦苦等待, 结果就是造成资源的浪费。第三次握手就是为了防止失效的连接请求到达服务器,让服务器错误打开连接。
理解三次握手的正确姿势
(1)第一次握手,A向B发送消息后,B收到信息。B可确认A的发信能力和B的收信能力。
(2)第二次握手,B向A发送消息,A收到消息。A可确认A的发信能力和收信能力,A也可确认B的收信能力和发信能力。
(3)第三次握手,A向B发送消息,B接收到消息。B可确认A的收信能力和B的发信能力。
更加接地气的解释就是: A打电话给B
第一次握手: 你好,我是A,你能听到我说话吗
第二次握手: 听到了,我是B,你能听到我说话吗
第三次握手: 听到了,我们可以开始聊天了
三次握手其实就是为了检测双方的发送和接收能力是否正常,你说呢?
四次挥手
TCP通过四次挥手进行连接关闭。
四次挥手如何进行?
-
第一次挥手:Client发送一个FIN=1,seq=u用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
-
第二次挥手:Server收到FIN后,发送确认报文给Client,ACK=1,seq=v,ack=u+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。此时TCP链接处于半关闭状态,即客户端已经没有要发送的数据了,但服务端若发送数据,则客户端仍要接收。
-
第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
-
第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,等待2
- MSL(最大报文存活时间)后进入CLOSED状态。Server收到Client的ACK后进入CLOSED状态,完成四次挥手
为什么要四次挥手,而不是两次,三次?
(1)由于TCP的全双工通信,双方都能作为数据发送方。A想要关闭连接,必须要等数据都发送完毕,才发送FIN给B。(此时A处于半关闭状态)
(2)B发送确认ACK,并且B此时如果要发送数据,就发送(例如做一些释放前的处理)
(3)B发送完数据之后,发送FIN给A。(此时B处于半关闭状态)
(4)A发送ACK,进入TIME-WAIT状态
(5)经过2MSL时间后没有收到B传来的报文,则确定B收到了ACK了。(此时A,B才算是处于完全关闭状态)
为什么要等待2MSL?
在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
理解四次挥手的正确姿势
-
第一次挥手:A告诉B,我没数据发了,准备关闭连接了,你要发送数据吗
-
第二次挥手:B发送确认应答,如果有数据则再发送最后的数据
-
第三次挥手:B告诉A,我也要关闭连接了
- 第四次挥手:A告诉B你可以关闭了,我这边也关闭了