什么是TCP中三次握手和四次挥手
简述
该题主要是考察网络基础,属于很常规的题目,而且问到的频率很高哦。
答案
三次握手:
- 第一次: 客户端向服务器发送连接请求,这时候会发送一个sync(i)包,同时客户单进入到sync_send状态
- 第二次:服务端收到了客户端的sync请求,回复一个sync包,包中携带ack(i+1)和服务端的sync(j)信息,服务端进入sync_recv状态
- 第三次:客户端收到服务端的sync包,向服务端发送ack(j+1)包,该包发送完毕后,并且服务端收到ack包后,则双方进入establish状态,即连接建立
如图所示:
有个形象的例子, A和B打电话:
A: 喂,你那边可以听见么?
B: 可以听到,你可以听见么?
A: 可以听见。
四次挥手:
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。
这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。
首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
注意:中断连接端可以是客户端,也可以是服务端,这里以客户端主动断开为例来说明:
- 第一次: TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。
- 第二次:服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
- 第三次:服务器关闭客户端的连接,发送一个FIN给客户端。
- 第四次:客户端发回ACK报文确认,并将确认序号设置为收到序号加1。
如图所示:
有个形象的例子, A和B挂电话为例子:
A: 喂,我这边说完了,你说完了吧?
B: 是的
B:我挂了啊?
A: 收到。(B挂电话进入close状态)
A由于不确定B是否已经挂了电话,要等两个最大报文段生存时间关闭
相关问题
问题1. 为什么连接的时候是三次握手,关闭的时候却是四次握手?
因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
问题2. 为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的ACK报文。另一方面是为了保证在2MSL期间,该连接的本地端点地址(IP+PORT)不被再次使用,避免可能的较早连接请求到达,被误认为时新连接请求。