【网络】详解TCP协议中的可靠传输

一. TCP协议段格式

在这里插入图片描述

TCP协议段格式相比UDP要复杂很多,很多内容需要我们了解TCP的一些特性后才能理解,为了理解TCP传输的可靠性,此处需要重点关注32位序号,32位确认序号,ACK这几个组成部分。

二. 确认应答——确保可靠性的核心机制

这里所谓的可靠性,并不是说我们发出的数据对方一定会接收到(真实的网络情况特别复杂,各种意外情况都存在,比如:挖掘机铲断网线/光纤、接收方停电),而是说尽可能地去保证对方能够接收到数据,并且发送方能够知道对方是否有收到这部分数据。

1.确保时序

由于真实的网络情况比较复杂,极有可能出现后发先至的情况,那此时表达的逻辑含义就有可能出现错误。
在这里插入图片描述
为了解决这个问题,引入了32位序号,32位确认序号,对数据进行编号,应答报文里就告诉发送方说,我这次应答的是哪个数据。
在这里插入图片描述
由于TCP是面向字节流的,所以编号也是相对于字节。TCP就对每个字节都进行了编号(实际情况不是从1开始编号,这里是简化了模型)。
在这里插入图片描述
那这里的32位序号存储的就是发送数据的第一个字节的编号;32位确认序号存储的就是本次发送数据的最后一个字节的序号+1。(比如这张图片中的序号1和确认序号1001)。
对数据进行编号后,想要达到不出现“后发先至”的情况,实际上还依赖于接收缓冲区。即数据到达接收方后并不会被应用层直接读走,而是要在接收缓冲区排好顺序,再依次读走,如果出现“后发先至”的情况,数据就会在接收缓冲区等待序号靠前的数据。

2.确保发送方知道数据是否被对方接收到

这个有赖于“ACK”(acknowledge)的作用,上面图片中提到的确认应答(应答报文,无载荷,只是告诉对方数据收到或没有收到)。在正常发送的报文中,ACK这一位为0,而在应答报文中,这一位为1。

结合ACK和序号/确认序号
在这里插入图片描述
如果没有返回确认应答(ACK报文)或者返回的确认应答中确认序号不对(比如发送数据1001~2000之后,仍然返回确认序号为1001的ACK报文),此处就要涉及到超时重传

三. 超时重传

没有收到ACK报文的情况主要有两种:
在这里插入图片描述

1. 发送的数据丢包

这种情况接收方本来就没有接收到数据,此时重传没有任何问题。

2. ACK报文丢失

这种情况下也会引起超时重传,但显然此时接收方已经拿到了数据,只是没有返回ACK报文而已。此时重传数据,就会引起数据的重复。那这样的问题如何解决呢:
答案是依赖于接收缓冲区的去重功能核心判定依据为数据的序号。此处可能有以下几种情况:

  1. 数据还在接收缓冲区里,没被应用程序读走
    这种情况比较简单,此时就是拿着新收到的数据的序号,和缓冲区中的所有数据的序号对一下,有一样的就是重复发送,就要把新收到的数据丢弃掉。
  2. 数据已经被应用程序读走
    应用程序从接收缓冲区中读取数据是按照序号的先后顺序,连续读取的。一定是先读序号小的,再读序号大的数据。此时socket api就可以记录上次读的最后一个字节的序号是多少。那如果重传来的数据序号比这个记录值小,就说明重复了,会被抛弃掉。

虽然数据包会被丢弃掉,但是仍然要返回ACK报文,否则发送方没有接收到ACK报文,就会继续重传。

但是重传也不是无限的去重传,重传过程也有一定的策略:

  1. 重传次数是有上限的,重传到一定次数,如果还没有ack,就尝试“复位”连接,如果仍然不行,就单方面的放弃连接。
  2. 重传会随着重传次数的增加越来越慢,重传频率会越来越低。

比如说在一次网络通信的过程中,丢包的概率为10%(相较于现实情况很大,为了简化模型),那传输一次的成功率就是90%,传输两次的成功率就是99%(90%+10%*90%),传输三次的成功率就是99.9%(99%+1%*90%)…

也就是说如果多次传输仍不能到达,大概率是出现了比较严重的网络问题,此时少重传几次,也可以节约开销。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值