一、答案
对字节流分段并进行编号然后通过 ACK 回复和超时重发这两个机制来保证。
二、分析
TCP 协议是架设在 IP 协议之上的传输层协议,尽管 TCP 是以字节流的方式进行传输,但是其内部还是依靠 IP 层的数据包的形式进行通信。
很惨,为了适应 IP 层以数据包的方式进行沟通的方式,TCP 层不得不将字节流拆分成若干个小的数据包(segment),在每个 segment 头部挂上 TCP 协议头,上面写明该 segment 的第一个字节在整个字节流的位置,即:seq 。同时写明该 segment 的字节数量,即:Data offset = len。
通过上述记录的信息,接收端会推断出下一个 segment 在整个字节流的位置(seq + len)。当下一个包到来时,接收端判断该包的 seq 是否符合要求,若符合则回复 ACK,若不符合则接收端可以直接丢弃该包(若直接丢弃,则说明滑动窗口大小为1)。
发送端若接收到 ACK,则说明之前发送的包的顺序都是没有问题的,则发送下一个包。若一段时间之内没有接收到 ACK,则有如下可能:
- 上一个包接收端没有收到,从而重发该包。
- 接收端收到了上一个包,但是回复的 ACK 丢失,那么发送端依然会重发上一个包。接收端收到该包之后就明白上一个ACK 发送失败,则接收端会再次发送 ACK 包。
经过上述一系列操作,TCP / IP 可以保证数据可以有序并且可靠的发送至接收端。但是有个问题,因为发送端每发送一个包,接收端就要回复 ACK,这就导致了网络吞吐量太低!对于该问题,后序文章会讲解解决方案。
(SAW:Game Over!)