TCP的三次挥手、四次握手

三次握手

相关参数的描述:

消息类型描述
SYN 同步序列编号用来初始化和建立连接的
ACK 确认字符帮助对方确认收到的SYN消息
SYN-ACK本地的SYN消息和较早的ACK数据包
FIN用来断开连接

SYN:同步序列编号,是TCP/IP建立连接使用的握手信号。在客户机和服务器之间建立TCP连接时,首先会发送一个信号。客户端在接收到SYN消息时,就会在自己的段内生成一个随机值X。

SYN-ACK:服务器收到SYN后,打开客户端连接,发送一个SYN-ACK作为答复。确认号设置为比接收到的序列号多一个,即X+1,服务器为数据包选择的序列号是另一个随机数 Y

ACK:确认字符,表示发来的数据已确认接收无误。最后,客户端将ACK发送给服务器。序列号被设置为接收的确认值即Y+1

最开始,客户端和服务器端都是处于CLOSED closed状态。先是服务器端主动监听某个端口,处于LISTEN状态。listen状态

  1. 客户端会随机初始化序号(client_isn),将此序号置于TCP首部的序号字段中,同时把SYN标志位置为1,表示SYN报文。接着把SYN报文发送到服务器端,表示想服务器发送连接,该报文不包含应用层的数据,之后客户端处于SYN-SENT状态(请求连接状态)。

  2. 服务器端收到客户端的SYN报文后,首先服务器端会自己初始化自己的序列号(server_isn),将次序号填入TCP首部的序号中,其次把TCP首部确认应答号字段填入client_isn + 1,接着把SYN和ACK标志位置为1,最后将该报文发送给客户端,该报文不包含应用层的数据,之后服务器处于 SYN-RCVD状态。接收状态

  3. 客户端收到服务器端报文后,向服务器端响应最后一个应答报文,首先该应答报文TCP首部ACK标志位置为1,其次确认应答号字段填入server_isn + 1,最后把报文发送给服务器端,报文中携带客户到服务器的数据,之后客户端处于ESTABLISHED状态(established连接成功状态)。

  4. 服务器端收到客户端的应答报文户,也进入ESTABLISHED状态。

第三次握手是可以携带数据的,前两次握手是不可以携带数据的,一旦完成三次握手,双方都处于 ESTABLISHED 状态,此时连接就已建立完成,客户端和服务端就可以相互发送数据了。

举例:

小明-客户端 小红-客户端

小明给小红打电话,接通后,小明说可以听到吗,相当于是连接建立

小红给小明回应,能听到我说话吗,相当于请求响应。

小明听到小红的回应后,好的,想防御连接确认,之后小明和小红就可以通话/交换信息。

总结:

        首先客户端向服务端发送连接请求,并发送SYN报文,之后处于请求连接状态;之后服务器端收到客户端的SYN报文后,将SYN和ACK置为1,将报文发送给客户端,之后服务器由监听状态转换为接收状态,此时客户端接收到了服务器的报文后,将相关的数据和报文一起发送给服务器。最后服务器和客户端都进了连接成功状态。

clinent_isn:客户端序列号 server_isn : 服务器端序列号

  • 前置条件:客户端和服务器处于关闭状态。首先服务端进入监听状态

  • 第一次:客户端向服务器端发送SYN(=1)报文,并进入请求连接状态(随机初始化clinent_isn)

  • 第二次:服务器端接收到客户端的SYN请求后,将SYN和ACK置为1,将报文发送给客户端,服务器端进入接收状态(随机初始化server_isn,并将clinent_isn + 1 )

  • 第三次:客户端收到了服务器的ACK报文后,将发送的数据和报文一起发送给服务器端,进入连接成功状态(server_isn + 1)

  • 最后条件:客户端和服务器端都进入了连接成功状态

为什么要三次握手?

三次握手时为了建立可靠的通信信道,收到通讯,简单来说就是数据的发送和接收,而三次握手最主要的目的就是双方确认自己与对方的发送和接收是正常的。

第一次握手,客户端什么都不能确认;Server确认了对方发送正常自己接收正常

第二次握手:客户端确认自己和客户端发送、接收正常;服务器端确认客户端发送正常,自己接收正常

第三次握手:客户端确认了,自己和对方接收、发送正常;服务器端确认自己和客户端发送、接收正常。

三次握手保证了服务器端和客户端双方都发送和接收正常。

因为三次握手才能保证双方具有接收和发送的能力。

为什么是三次握手?不是两次、四次?

因为三次握手才能保证双方具有接收和发送的能力。

为什么三次握手才可以初始化Socket、序列号和窗口大小并建立 TCP 连接?

  • 可以阻止重复历史连接的初始化(主要原因)

    为了防止旧的重复连接初始化造成混乱,如果是两次连接,无法确定当前连接是否是历史连接,三次握手则可以在客户端准备发送第三次报文时,客户端有足够的时间来判断是否为历史连接。

    • 如果是历史连接(序列号过期或超时),则第三次握手发送的报文是 RST 报文,以此中止历史连接;

    • 如果不是历史连接,则第三次发送的报文是 ACK 报文,通信双方就会成功建立连接;

  • 可以同步双方的初始序列号

    两次握手只保证了一方的初始序列号能被对方成功接收,没办法保证双方的初始序列号都能被确认接收。

  • 可以避免资源浪费

    如果只有「两次握手」,当客户端的 SYN 请求连接在网络中阻塞,客户端没有接收到 ACK 报文,就会重新发送 SYN ,由于没有第三次握手,服务器不清楚客户端是否收到了自己发送的建立连接的ACK 确认信号,所以每收到一个 SYN 就只能先主动建立一个连接,这会造成什么情况呢? 如果客户端的 SYN 阻塞了,重复发送多次 SYN 报文,那么服务器在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费。

TCP 建立连接时,通过三次握手能防止历史连接的建立,能减少双方不必要的资源开销,能帮助双方同步初始化序列号。序列号能够保证数据包不重复、不丢弃和按序传输。不使用「两次握手」和「四次握手」的原因:

  • 两次握手:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;

  • 四次握手:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。

第 2 次握手传回3了 ACK,为什么还要传回 SYN?

      接收端传回发送吨所发送的ACK是为了告诉客户端,我接收到的信息确实就是你所发送的信号,这表明从客户端到服务器端的通信是正常的,而回传SYN则是为了建立并确认从服务器端到客户端的通信。

四次挥手

通过四次挥手,双方都可以主动断开连接,断开连接后主机中的资源将被释放。

四次挥手:每个方向都需要一个FIN和一个ACK

主动关闭连接的,才有 TIME_WAIT 状态。

  • 客户端打算关闭连接,会发送一个TCP首部FIN标志位置为1的报文,即FIN报文,之后客户端进入FIN_WAIT_1 状态

  • 服务器端收到报文后,向客户端发送ACK应答报文,接着服务器端进入CLOSED_WAIT 状态(等待关闭状态)。

  • 客户端收到服务器端的ACK应答报文后,进入FIN_WAIT_2状态

  • 服务器处理完数据后,向客户端发送FIN报文,之后服务器端进入, LAST_ACK 状态

  • 客户端收到服务器端的FIN报文后,回应一个ACK应答报文,进入TIME_WAIT状态。

  • 服务器端收到了ACK应答报文后,就进入了CLOSED状态,到此服务器端已经完成连接的关闭。

  • 客户端在经过2MSL一段时间后,自动进入CLOSED状态,客户端也完成连接的关闭

 举例:

1. A和B打电话,通话即将结束,A说我没有什么可以说的了,B回答我知道了,但是B可能还没有说完,A有不能要求B跟着自己的节奏结束通话,于是B可能又说一些,最后B说我说完了,A回答我知道了,通话结束。

2. 

  • 客户端---小明 服务器端---小红

  • 小明对小红说,我所有的东西都说完了,我要挂电话了

  • 小红说,收到,我这边这些一些东西没说

  • 经过若干秒后,小红也说完了,小红说,我说完了,现在可以挂断了

  • 小明收到消息后,又等了若干时间后,挂断了电话

总结

  • 客户端发送一个FIN,用来关闭客户端到服务器的数据传送
  • 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
  • 服务器端关闭与客户端的连接,发送一个FIN给客户端
  • 客户端发回ACK报文确认,并将确认序号设置为收到序号加1

        任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。

四次挥手双方发 FIN 包的过程,就能理解为什么需要四次了?

  • 关闭连接后,客户端向服务端发送FIN时,仅仅表示客户端不再发送数据了,但是还是可以接收数据

  • 服务器端收到客户端FIN报文时,先回一个ACK应答报文,而服务端可能还有数据需要处理和发送,等服务器端不再发送数据时,才发送FIN报文给客户端来表示同意现在关闭连接

       从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK 和 FIN 一般都 会分开发送,从而比三次握手导致多了一次。

为什么 TIME_WAIT 等待的时间是 2MSL?

        MSL是Maximum Segment Lifetime,报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为TCP报文基于是IP协议的,而IP头中有一个TTL字段,是IP数据报可以经过的最大路由数,每经过一个处理的它的路由器此值就减一,当此值为0,则数据报将被丢弃,同时发送ICMP报文通知源主机

MSL 与 TTL 的区别: MSL 的单位是时间,而 TTL 是经过路由跳数。所以 MSL 应该要大于等于 TTL消耗为 0 的时间,以确保报文已被自然消亡。

TIME_WAIT 等待 2 倍的 MSL,比较合理的解释是: 网络中可能存在来自发送方的数据包,当这些发送方的数据包被接收方处理后又会向对方发送响应,所以一来一回需要等待 2 倍的时间

总结:

TCP协议如何保证可靠传输?

  1. 应用数据被分割成 TCP 认为最适合发送的数据块。
  2. TCP 给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
  3. 校验和: TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
  4. TCP 的接收端会丢弃重复的数据。
  5. 流量控制: TCP 连接的每一方都有固定大小的缓冲空间,TCP 的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议。 (TCP 利用滑动窗口实现流量控制)
  6. 拥塞控制: 当网络拥塞时,减少数据的发送。
  7. ARQ 协议: 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
  8. 超时重传: 当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值