浅谈传输层协定(二):TCP 到底多可靠?

上一篇 TCP 在做什麽?简单介绍了 TCP 大致的框架,以及是如何建立连线的,今天来看看为何 TCP 是一个可靠的协定?

TCP 怎麽检查你的资料有没有损坏?

首先我们先来看看资料「损坏」这件事情。现实世界中的如果送包裹,过程中没有压到、摔到,完好无缺的抵达目的地,我们就说这个包裹没有损坏。但在网路世界不太一样,资料被转换成电流或是无线电波传送,如果突然打了个雷之类的让介质中有什麽干扰,传播中的资料肯定就此毁坏。

还好,我们传送的资讯都数位化了,如果这次传送的资讯坏了会没收到,大不了再传一次,成本反正很低,这可是真实世界的包裹难以达成的。也就是说,如果资料「损坏」了,在网路世界只要重新传送就好,重点就在怎麽检查资料在传输过程中还完不完好。

由於资料会被拆成数个封包传送,TCP 找出错误的方式便有以下几种方式:检验资讯是否有误封包掉了就重送看看序号是否连续

序号连续这件事在聊 TCP 三向交握的时候提了一些,所以我们接着来看看检验资料错误和重送机制吧。

Checksum 检验和

要检验资讯是否有误,TCP 的解法是 Checksum,就是检验某些数值的加总是否一致,这在计算机领域也是常用来做错误侦测的一种方法。

由於传输的资料是数位的,最基本的模样由 0 和 1 所组成,我们 TCP 就把 Port、序号、要传的资料等等这些数字化的资讯加总在一起,所以称做检验「和」(Sum)。这个「和」也会被放在这笔资料内一起送出去,接收的时候把传送的资料和这个「和」验证一下。

举个例子来说,我们传的资料是 1 3 5 7 9 1,Checksum 就是把这些数字加起来,得到 26。但是当然不会把加起来的数字直接传过去,因为要传的资料可能很长,得到的 Checksum 就会很大,TCP 的定义不容许太大的 Checksum 存在,因此我们可以对这个 Checksum 做点调整,例如取个除以 10 的余数,26 % 10 = 6

------- 1 3 5 7 9 1 ------->
1 + 3 + 5 + 7 + 9 + 1 = 26
26 % 10 = 6

把取完的余数 6 一起传过去,接收的时候重新加一下验证是否等於 6,如果不是的话,就重新传送一次。以上例子并非 TCP Checksum 真实的情境,只是把概念用一般人比较容易理解的 10 进制来表示而已。

大致了解 Checksum 之後,你可能会想问,有没有可能传的资料错了,但得出的 Checksum 还是一样的?

很有可能。

机率大约是 0.0016%。你可能觉得机率蛮低了,但放大到每天不知道多少笔的 TCP 封包在网路上跑着,根据大数法则,发生错误没被揪出来的封包比比皆是。

所以说,Checksum 虽然能揪出大部分的错误,但其实算是蛮脆弱的错误检验机制,现在是依靠着网路模型中其它层也会做的一些错误检测机制,一起和 TCP 避免资料的错误产生。

TCP 虽然号称可靠的传输协定,但重点还是摆在让要传的封包一定会传到目的地,或是传不到也一定让你知道。

逾时重送、壅塞控制、流量控制

那麽,TCP 要怎麽确保送的封包已经到达目的地了呢?其实方法说起来也很简单,靠的就是它的内建计时器。

如果我方已经将封包送出一阵子了,还没得到对方回应说收到,很有可能这个封包在路上就挂了。所以 TCP 会在送出封包後计时,1 秒钟 2 秒钟 …,时间到。还没收到回覆,再送一次。

具体计的时间其实不是固定的数值,刚开始可能从 10 毫秒等起,如果没得到回覆,下次就等 20 毫秒、40 毫秒,以此类推,这种做法也是因为怕说到目的地的路径太壅塞了,如果我相同时间一直疯狂重送封包,可能让路径更塞。

有了壅塞的状况,也可能会有一路畅通,传的太快让收的那方措手不及的情形发生,这时 TCP 也会跳出来做流量的控制。

具体怎麽做的呢?就是将来得太快的资料放在如同行李转盘的记忆体上,慢慢消化,如果转盘已经放满资料了,接收方就会叫传送方先别传了,等一等再来。

以上为 TCP 对於资料传输的简介,而在传输层还有另一大协定 UDP 呢,我们接着来看看。

  1. NotFalse 技术客 - TCP 错误控制
  2. Wiki - Checksum
  3. NotFalse 技术客 - TCP Checksum
  4. StackOverflow - Can a TCP checksum fail to detect an error? If yes, how is this dealt with?
  5. StackExchange - If TCP is a reliable data transfer method, then how come its checksum is not 100% reliable?

<<:  Day15-旧网站重写成Vue_6_多图片轮播

>>:  16 综观各校资工系修课蓝图

Day 12 - OOP 初探 (2) - Class

前言 昨天讲完 Javascript OOP 两个重要支柱,今天接着这个主题,来讲讲 class 吧...

Day 16 ( 中级 ) 水底探照灯

水底探照灯 教学原文参考:水底探照灯 这篇文章会介绍,如何在 Scratch 3 里使用舞台九倍大角...

Day 8:先别急着撰写文章,你听过 Markdown 吗?

相信有人已经迫不及待要撰写文章了,不过在这之前,我们先来介绍一下 Markdown 这个标记语言。 ...

[Python 爬虫这样学,一定是大拇指拉!] DAY02 - 关於 Python (1)

所谓工欲善其事,必先利其器。 选择 Python 的理由又是什麽? 那我们得先从语言的特性及优缺点来...

IT铁人第28天 Elasticsearch 使用python查询资料 Aggregations:Sum/Value Count

今天文章的内容是Sum(总和)跟Value Count(数量计算) 今天的示范资料 Sum Sum大...