TCP的三次握手和四次挥手


提示:以下是本篇文章正文内容,如有错误,请及时指正。


TCP 的连接管理机制

TCP,提供面向连接的服务,在传送数据之前必须先建立连接,数据传送完成后要释放连接。

建立连接(三次握手)

在这里插入图片描述

如图上所示:主机 A 想要与 主机B 建立连接,双方就都要发送同步报文段 ,而在 TCP 报头中的6位标记位中对应的 SYN 为 1 就表示该报文段是同步报文段

第一次握手:主机 A 发送一个同步报文段 SYN 给主机 B。

第二次握手:主机 B 收到这个同步报文段 SYN 之后,就知道了要双方要建立连接传数据了,就会回复一些内容给主机 A,内容就有确认应答 ACK + 同步报文段 SYN。因为在网络种传输数据开销是很大的,所以这个第二次连接就一起传输了。

第三次握手:主机 A 收到 SYN + ACK 之后就会再给主机 B 发送一个 ACK,于是通信双方就建立了。

问题一:为什么建立连接是三次握手?

答:只有经历了三次握手通信双方才能确定对方和自己的发送能力和接收能力都是正常的,如下图所示,按顺序阅读。在这里插入图片描述

问题二:可以是两次握手吗?

答:不能,还是用上面的图,两次握手接收方 B 不能确定自己的发送能力和 A 的接收能力 OK。

问题三:可以是四次握手吗?

答:可以,把第二次握手 B 发送给 A 的 ACK 和 SYN 分两次发送,就是四次握手了,但是完全没有必要这样做,。因为它们都是由操作系统内核管理的,所以一定会发送在同一时机。

释放连接(四次挥手)

在这里插入图片描述

如图上所示:想要断开连接,通信双方就要发送结束报文段,FIN 为1,就表示该报文段是结束报文段

第一次挥手:主机 A 发送一个结束报文段 FIN 给主机 B。

第二次挥手:主机 B 收到这个结束报文段 SYN 之后,就知道了 A 要断开连接了,于是就会先给主机 A 发送一个确认报文 ACK (意思就是告诉主机 A ,我知道了,不过得先等一会)

第三次挥手:主机 B 向主机 A 又发送了结束报文段 FIN 。

第四次挥手:主机 A 收到这个结束报文段 FIN 后,再给主机 B 发送一个确认报文段,释放连接到此结束。

问题:断开连接时,第二次和第三次的主机 B 回复给主机 A 的 FIN 和 ACK能否合并在一起?

答:答案是不一定的。
不能合并的理由是:发送的 ACK 和 FIN 的时机是不一样的,发送 ACK 是操作系统内核的行为,在收到 FIN 的第一时间就回复了 ACK,而发送 FIN 是的应用程序的行为,需要在代码中执行到对应的 “close()” 才会触发 FIN。(这也是为什么上面提到的要等一会的原因)
能合并的理由是:如果 “close()” 能够很快被调用,FIN 和 ACK 的间隔时间很短,就会触发 TCP 的 “延时应答+捎带应答”机制,于是它俩就合并在一起了,就变成了三次挥手。

提示:关于三次握手和四次挥手的过程中也会存在数据的丢失,如果数据丢失,就会涉及到超时重传,和传输数据时一样的,想要了解这其中详细经过,可以看这个TCP 的那些事儿.

连接和释放的状态分析

如图所示

服务器端状态转化

  • [CLOSED -> LISTEN] :服务器端调用listen后进入LISTEN状态, 等待客户端连接;
  • [LISTEN -> SYN_RCVD] :一旦监听到连接请求(同步报文段), 就将该连接放入内核等待队列中,并向客户端发送SYN确认报文.
  • [SYN_RCVD -> ESTABLISHED] :服务端一旦收到客户端的确认报文, 就进入ESTABLISHED状态,可以进行读写数据了.
  • [ESTABLISHED -> CLOSE_WAIT] :当客户端主动关闭连接(调用close), 服务器会收到结束报文段, 服务器返回确认报文段并进入CLOSE_WAIT;
  • [CLOSE_WAIT -> LAST_ACK] :进入CLOSE_WAIT后说明服务器准备关闭连接(需要处理完之前的数据); 当服务器真正调用close关闭连接时, 会向客户端发送FIN, 此时服务器进入LAST_ACK状态, 等待最后一个ACK到来(这个ACK是客户端确认收到了FIN)
  • [LAST_ACK -> CLOSED] :服务器收到了对FIN的ACK, 彻底关闭连接.

客户端状态转化:

  • [CLOSED -> SYN_SENT]: 客户端调用connect, 发送同步报文段;
  • [SYN_SENT -> ESTABLISHED] :connect调用成功, 则进入ESTABLISHED状态, 开始读写数据;
  • [ESTABLISHED -> FIN_WAIT_1] :客户端主动调用close时, 向服务器发送结束报文段, 同时进入FIN_WAIT_1;
  • [FIN_WAIT_1 -> FIN_WAIT_2] :客户端收到服务器对结束报文段的确认, 则进入FIN_WAIT_2, 开始等待服务器的结束报文段;
  • [FIN_WAIT_2 -> TIME_WAIT]:客户端收到服务器发来的结束报文段, 进入TIME_WAIT, 并发出LAST_ACK;
  • [TIME_WAIT -> CLOSED] :客户端要等待一个2MSL(Max Segment Life, 报文最大生存时间)的时间, 才会进入CLOSED状态.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值