TCP是如何实现可靠传输的?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP是如何实现可靠传输的?相关的知识,希望对你有一定的参考价值。

参考技术A

在计算机网络的经典五层协议中,TCP属于运输层,实现了进程间的通信,保证了数据的可靠传输,属于计算机网络协议族中最重要的协议之一,那么TCP是如何实现可靠数据传输的呢?

运输层的进程间通信是通过socket实现的,socket是一个抽象的概念,在Linux系统中以文件的形式存在。网络层通过IP来区分主机,运输层则增加了端口的概念来区分进程。TCP协议中使用目标IP、目标端口、源IP、源端口来定义一个socket,只需要在运输层的报文头部附加上这些信息,目标主机就会知道数据要发送那个socket,对应监听该socket的进程就可以收到数据进行处理。

TCP报文包括首部和数据部分,首部附加了TCP报文的信息,首部长度固定部分为20字节,还有40字节的可选部分,具体如下图所示:

其中几个关键字段的作用如下:

网络层只管尽可能将数据从一个主机发送到另一个主机,并不保证数据可靠到达,由于网络环境总是不稳定的,可能存在丢包、差错等请求,TCP则通过一系列的机制在运输层保证了数据的可靠传输。
网络传输可能发生的异常情况和解决方法:

要实现可靠传输,最简单的方法就是发送方发送一个报文,接收方收到报文后发送确认报文表示我收到了,你可以发下一个了,传输模型如下:

这种方式保证可靠传输称为停止等待协议,这种方式缺点也很明显,效率非常低。

为了提高传输效率,充分利用带宽,发送方会连续的发送数据包,如下图所示:

客户端不等收到前一个包的确认报文就开始不断的发下一个包,这样可以充分利用网络带宽,提高传输效率,但是于此同时也带来了另外的问题,那么TCP是如何解决这些问题的?

累计确认 :网络中充斥着大量的发送包和确认回复报文,这些数据只是为了确认报文到达,并不是实际需要传输的数据。是不是一定要每一个报文都要发一个回复确认的报文呢,TCP采用了累计确认的方法:接收方在累计收到了一定量的数据包后发送一个确认报文告诉发送方在此之前的数据包都已经收到了,这样便可以减少确认报文的数量,提高带宽利用率。

GBN(回退n步) :如果发生丢包的情况,在连续ARQ中,如果接受方收到了123 567个字节,编号为4字节的包丢失了,按照累计确认只能发送3的确认回复,567都要丢掉,因为发送发会进行重传。

选择确认ACK :在TCP报文头部的选项字段部分设置已收到的报文,每一段用两个边界来确定,比如上述情况可以用[1,3]和[5,7]来表示,客户端就会根据选项只重传丢失的数据段。

因为接收方读数据的能力有限,发送发不能一直发送报文直到把缓冲区所有数据发送完,这样会导致接收方无法接收丢弃掉数据包,发送方收不到确认认为超时又会继续重传,产生了大量无用数据的重传。对此情况TCP使用滑动窗口来解决,基本模型如下:

滑动窗口机制实现了TCP的 流量控制 ,不至于发送太快导致太多的数据丢弃和重传。

为了避免网络过分拥挤导致丢包严重,传输效率低,TCP实现了拥塞控制机制,拥塞控制的解决办法本质上是流量控制,控制发送方发送的速度,而上文提到流量控制是通过滑动窗口来实现的,所以最终也是通过调整发送方的滑动窗口大小来实现的。

拥塞控制的几个重要的概念:慢启动、拥塞避免、快恢复、快重传

Reno算法是比较常见的TCP实现的拥塞控制算法,其他拥塞算法还有Tahoe(已废弃不用)、New Reno等,通过拥塞控制算法可以很大程度避免网络拥挤。

【书籍】计算机网络:自顶向下方法
【码农有道】 这一篇TCP总结请收下

计算机网络TCP协议

目录

TCP协议

TCP协议是什么

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793 定义。TCP应用层次是传输层。

TCP协议的特点

应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元(MTU)的限制)。之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。
TCP的职责是进程到进程之间的通信。TCP保证了可靠性。
TCP的可靠性:
(1)TCP尽它最大可能,将数据发送给对方
(2)即使数据没有发送给对方,TCP会给上层(进程)一个交代
(3)保证接收方接收到的数据都是有序的
(4)TCP可以保证不会接收到错误的数据
(5)根据接收能力和网络承载情况做了发送量控制

TCP协议实现机制

TCP如何实现进程到进程

数据通过互联网传输的时候不是单纯的数据,不加任何标识,如果这样数据实现不了指定进程到进程的通信。所以数据在发送的时候,需要加上特定标识,加上特定标识的过程叫做数据的封装,在数据使用的时候再去掉特定标识,去掉特定标识的过程就叫做分用。TCP的4位首部长度就是做解包用的。

TCP如何实现可靠性

TCP中有确认应答机制。确认应答机制是收到一条报文后,向发送端发送一条确认ACK,此ACK的作用就是告诉发送端:接收端已经成功的收到了消息,并且希望收到下一条报文的序列号是什么。确认序号(Acknowledgment Number)标识了报文接收端期望接收的字节序列。

校验和:
长度为16位,共2个字节。对整个TCP报文段,即TCP头部和TCP数据进行校验和计算,接收端用于对收到的数据包进行验证。

超时重传

在数据发送过程中,我们不应该有上帝视角。在进程到进程通信中。发送端发送数据后,过了很久都没有收到应答,可能有什么原因?

(1)对方完全没有收到数据
a.数据丢了
b.因为时间原因,数据还没有到达对方(因为时间过了很久,所以此项原因我们不考虑)
(2)对方已收到数据,只是应答我们没有收到
a.应答丢了
b.应答因为时间原因,我们还没有收到(因为时间过了很久,所以此项原因我们不考虑)

发生以上这种情况时,我们有一个超时重传机制。
TCP的重传存在原因就是为了保障TCP的可靠性,正是由于TCP存在重传的机制,那些基于TCP的业务应用在网络交互的过程中,不再担心由于丢包、包损坏等导致的一系列应用问题了。
在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止。一个报文段可以好几次的超时,也就是说,第一次发此报文段时超时了,发送端会重新发送,第二次发的时候还是超时了,此时发送端还是会重新发送,但是发送端对一个超时的报文段不会一直发,发几次之后,就会丢弃此报文段。

计时器设置的时间在好几次的发送中,为什么要变得越来越长呢?

因为在发送数据的时候,数据传输可能还没建立好,此时就重传,可能会浪费资源。

延时应答

数据传输的时候,发送端给接收端发送数据,接收端给发送端发去确认应答信息,这样比较耗时,效率低下,延迟应答就是接收端收到数据之后,稍微等一会再应答,这样可以提高数据的传输效率,因为发送端发好几次数据,接收端只需要一次来确认应答,这样可以降低网络拥塞的概率
数量限制:每隔N个包就必须应答一次
时间限制:超过最大延迟时间就必须应答一次

所有的包都可以延迟应答吗?
不是。


以上是关于TCP是如何实现可靠传输的?的主要内容,如果未能解决你的问题,请参考以下文章

面试官:说说TCP如何实现可靠传输

TCP协议如何保证可靠传输

UDP如何实现可靠传输

TCP的不可靠传输

用UDP实现可靠传输

udp如何实现可靠性传输?