25

笔记 | 面试又挂了,只因问了:TCP三次握手和四次挥手

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzA5NTUzNTA2Mw%3D%3D&%3Bmid=2454934505&%3Bidx=1&%3Bsn=388f9b70b5e5a1791f79ba66de471152
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

面试官:跟我讲讲TCP的三次握手和四次挥手流程,为什么是三次握手或四次挥手?

面试者:额......不太记得了.....gg..

在前面的文章知道, 《TCP与UDP的区别 ,到 《TCP是如何保证可靠性 。那么接下来就是TCP的核心了,即TCP的可靠性依赖其:三次握手和四次挥手。

先思考下这三个面试题:

1、TCP 为什么三次握手而不是两次握手?

2、为什么连接的时候是三次握手,关闭的时候却是四次握手?

3、为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

在TCP/IP协议中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号并交换 TCP窗口大小信息。

tcp三次握手和四次挥手交互图:

BbMRRbR.png!web

三次握手:

  1. 第一次握手:建立连接。客户端发送连接请求报文段,将 SYN 位置为1, Sequence Number 为x;然后,客户端进入 SYN_SEND 状态,等待服务器的确认;

  2. 第二次握手:服务器收到 SYN 报文段。服务器收到客户端的 SYN 报文段,需要对这个 SYN 报文段进行确认,设置 Acknowledgment Number 为x+1( Sequence Number +1);同时,自己自己还要发送 SYN 请求信息,将 SYN 位置为1, Sequence Number 为y;服务器端将上述所有信息放到一个报文段(即 SYN+ACK 报文段)中,一并发送给客户端,此时服务器进入 SYN_RECV 状态;

  3. 第三次握手:客户端收到服务器的 SYN+ACK 报文段。然后将 Acknowledgment Number 设置为y+1,向服务器发送 ACK 报文段,这个报文段发送完毕以后,客户端和服务器端都进入 ESTABLISHED 状态,完成TCP三次握手。

四次挥手:

  1. 第一次挥手:主机1(可以使客户端,也可以是服务器端),设置 Sequence Number Acknowledgment Number ,向主机2发送一个 FIN 报文段;此时,主机1进入 FIN_WAIT_1 状态;这表示主机1没有数据要发送给主机2了;

  2. 第二次 挥手 :主机2收到了主机1发送的 FIN 报文段,向主机1回一个 ACK 报文段, Acknowledgment Number Sequence Number 加1;主机1进入 FIN_WAIT_2 状态;主机2告诉主机1,我“同意”你的关闭请求;

  3. 第三次 挥手 :主机2向主机1发送 FIN 报文段,请求关闭连接,同时主机2进入 LAST_ACK 状态;

  4. 第四次 挥手 :主机1收到主机2发送的 FIN 报文段,向主机2发送 ACK 报文段,然后主机1进入 TIME_WAIT 状态;主机2收到主机1的 ACK 报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。

三次握手可以简单通俗理解为:

1)A要跟B聊天,问B在吗(收到了吗)?(SYN)

2)B收到A,B回复A说收到了,那我们开始吧。(ACK+SYN)

3)A收到B的回复,A:那我们开始聊天(数据传输)。(ACK)

四次挥手可以简答理解为:

1)A跟B说,我要停止聊天了,你(B)还在吗?准备中断聊天了(FIN)

2)B收到A的消息,B回复A说:我在。(ACK)

3)B再发一条消息给A说,A你可以停止了。(FIN)

4)A收到B说可以停止发消息了,A回复B说:收到!(ACK)

1、TCP 为什么三次握手而不是两次握手?

为了实现可靠数据传输,TCP 协议的通信双方,都必须维护一个序列号,以标识发送出去的数据包中,哪些是已经被对方收到的。三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤。如果只是两次握手,至多只有连接发起方的起始序列号能被确认,另一方选择的序列号则得不到确认。

2、为什么连接的时候是三次握手,关闭的时候却是四次握手?

答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

3、为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可能最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。

文章关联→→:

抓包神器:Wireshark 实例分析TCP三次握手过程

笔记系列↓↓↓:

笔记 | Java对象探秘

笔记 | JVM内存区域结构:一计两栈一堆一区

笔记 | 并发编程的三大挑战

笔记 | TCP与UDP的区别

笔记 | TCP如何保证可靠性

参考: http://www.jellythink.com/archives/705


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK