TCP三次握手和四次挥手
《图解HTTP》
简单示意图:
- 客户端-发送带有SYN标志的数据包,一次握手–服务端
- 服务端-发送带有SYN/ACK标志的数据包-二次握手-客户端
- 客户端-发送带有ACK标志的数据包-三次握手-服务端
三次握手的目的
三次握手最重要的目的就是双方确认自己与对方发送与接受是正常的。
第一次握手:Client什么都不能确认;Server确认对方发送正常。
第二次握手:Client确认自己的发送,接受正常,对方发送接收正常;server确认了自己接收正常,对方发送正常;
第三次握手:Client确认了自己发送,接收正常,对方发送接收正常;Server确认了自己发送,接收正常,对方发送,接收正常。
为什么要传回SYN
接收端传回发送端的SYN是为了告诉发送端,我接收到的信息确实就是你发送的信号。
传了SYN,为啥还要传ACK
双方通信无误必须是两者相互发送信息都无误,传了SYN,证明发送方到接收方的通道没有问题,但是接收方到发送方的通道还需要ACK信号来验证。
断开一个TCP连接需要”四次挥手”:
- 客户端:发送一个FIN,用来关闭客户端到服务器的数据传送
- 服务器: 收到一个FIN,发回一个ACK,确认序号为接收到的序号加1,和SYN一样,一个FIN将占用一个序号
- 服务器: 关闭与客户端的连接,发送一个FIN给客户端
- 客户端: 发挥ACK确认报文,将确认序号设置为收到的序号加1
为什么客户端还要等待2MSL(MSL:报文最大生存时间)
第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK可能丢失,这样服务器
会重新发送一次,这样客户端在2MSL的时间内可以收到重传的报文,接着给出回应报文,并且重启2MSL计时器。
第二,防止类似和”三次握手”中提到的”已经失效的连接请求报文段“出现在本连接中,客户端发送完最后一个确认报文后,在这2MSL的时间内,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。
为什么建立连接是三次回收,关闭连接确是四次挥手?
建立连接的时候,服务器在LISTEN状态下,收到建立连接请求的SYN报文之后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据但是还是能接收到数据,而自己也未必全部数据都发送给对方,所以己方可以立即关闭,也可以发送一些数据对对方后,再发送FIN报文给对方来表示同意现在关闭连接。因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。
如果已经建立了连接,但是客户端突然出现了故障该怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。