TCP的三次握手和四次挥手

TCP的三次握手和四次挥手_第1张图片

TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接:

位码即tcp标志位,有6种标示:SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送) FIN(finish结束) RST(reset重置) URG(urgent紧急)

Sequence number(顺序号码) Acknowledge number(确认号码)

第一次握手:主机A发送位码为SYN=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1知道,A要求建立联机;

第二次握手:主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),SYN=1,ACK=1,随机产生seq=7654321的包;

第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ACK=1,主机B收到后确认ack number与ACK=1则连接建立成功。


TCP的三次握手和四次挥手_第2张图片


ESTABLISHED状态

第一次挥手:client发送FIN=1,seq=u,用来关闭client到server的数据发送,client进入FIN-WAIT-1状态

第二次挥手:server收到FIN,发送一个ACK,ack=收到序号+1,seq=v。server进入CLOSE-WAIT状态,此时TCP处于半关闭状态,client处于FIN-WAIT-2状态

第三次挥手:server发送一个FIN,seq=w,用来关闭server到client的数据传送,此时server处于LAST-ACK状态

第四次挥手:client收到FIN,进入TIME-WAIT状态(等待2MSL(报文最大生存时间)),发送ACK,ack=收到序号+1,server进入closed状态


TCP的三次握手和四次挥手_第3张图片

【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?

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

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

答:1.确保对方有足够时间收到ACK包,如果被动关闭的一方没有收到ACK包,就会重发FIN包,来回2MSL

      2.避免新旧混淆

【问题3】为什么不能用两次握手进行连接?

答:3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。

      现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,将不知道S 是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分 组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。

【问题4】如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

【问题5】服务器出现大量CLOSE-WAIT的原因

对方发送FIN后服务器没有发送ACK,可能是对方关闭socket,我方忙于读写


TCP的三次握手和四次挥手_第4张图片

你可能感兴趣的:(TCP的三次握手和四次挥手)