TCP 可靠传输

398 阅读9分钟

TCP 和 UDP的区别

传输层的主要任务就是负责向两台主机进程之间的通信提供通用的数据传输服务。应用进程利用该服务传送应用层报文。

传输控制协议,TCP:提供面向连接的,可靠的数据传输服务。

用户数据协议,UDP:提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)。

TCP

UDP

是否连接

面向连接

无连接

是否可靠

可靠传输,使用流量控制和拥塞控制

不可靠传输,不使用流量控制和拥塞控制

连接对象个数

只能是一对一通信

支持一对一,一对多,多对一和多对多交互通信

传输方式

面向字节流
(TCP一次传输的报文长度有限制,若太大则需分块、分次传输;但由于TCP连接的可靠性,接收方按顺序接收数据块并重新组成分块之前的数据流;所以TCP看起来就像直接互相传输字节流一样)

面向报文

首部开销

首部最小20字节,最大60字节

首部开销小,仅8字节

场景

适用于要求可靠传输的应用,例如文件传输

适用于实时应用(IP电话、视频会议、直播等)

什么是可靠传输?

1. 无差错。保证三点:reliable(不丢失无差错无重复), order, full use of link

解决办法:ARQ(自动重传请求协议)

2. 速度匹配:

无论发送方以多快的速度发送数据,接收方总来得及处理收到的数据

解决办法:**流量控制 & 拥塞控制协议 **

ARQ

Stop-and-Wait:

一次发一帧,等待确认。超时重传。

特点:

1. 可靠。不丢失无差错不重复,顺序对(2 bit sequence number就够)

2. 没把链接容量用满。

Concurrent Logical Channels:

在一个link里用多信道,每个信道都用stop-and-wait。

带宽用足了,但是顺序不保证对。(只要一个channel重新发送了一次,这个channel负责的包总是比别的channel晚一个)

Sliding Window: (go-back-n, selective-repeat)

Sender Parameters:

Send Window Size(SWS), Last Acknowledgement Received(LAR), Last Frame Sent(LFS)

发送窗口的任务:

分配序列号

收到ACK后,LAR前进,并且向前滑动窗口

Receiver Parameters:

Receive Window Size (RWS)

Next Frame Expected (NFE)

Last Fram Acceptable (LFA)

接收窗口的任务:

当数据包到来的时候,如果在窗口外,就扔掉;如果在窗口内,发送累计确认(cumulative ACK),向前滑动窗口

go-back-n:

发送窗口大小>1,接收窗口大小等于1

a. 发送方:采用多帧滑动窗口的原理,可连续发送多个数据帧 而不需等待对方确认

b. 接收方:采用累计确认。

如果有一帧丢失,发送窗口需重新发送N帧。

Packet 2 超时了,发送方依然没有接收到ACK2,发送方知道了Packet2丢包,于是重新发送错帧以及后面的几个帧。

本来都发到5了,现在只能回到2。所以叫go-back-n。

Selective Repeat:

发送窗口大小>1,接收窗口大小>1

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/dd823b7c333449738e4f9c232e07964a~tplv-k3u1fbpfcp-zoom-1.image)
2虽然丢了,但可以先接收3,4,5;等到2终于来了把2补上,接着发6,7,8

流量控制:

基于滑动窗口的流量控制

利用滑动窗口机制可以实现对发送方的流量控制。在TCP连接建立时,接收方会在确认报文段中给出自己接收窗口的大小。在每次发送确认报文时能够根据情况动态调整接收窗口的大小,并将告知发送方

发送方发送序号从1开始的100字节的数据,接收方在确认报文中声明自身的接收窗口大小为300字节。之后发送方发送300字节数据,接收方在确认报文中声明自身接收窗口大小调整为50字节。发送方再发送50字节数据之后,收到接收方传来的确认报文,在该报文中声明接收窗口为0。   **在接收方接收窗口为0时,发送方不再发送数据,直到接收方发送确认报文表明窗口大小发生改变**。可是这个确认报文不一定能够被发送方接收到,如果一旦该确认报文丢失,双方都将处于等待中,形成死锁。为防止这种情况出现,TCP规定在收到对方接收窗口为0时,启动一个坚持定时器周期性的发送**探测报文**,以确定对方接收窗口为0的状态是否改变。

       另外,TCP标准规定:接收方接收窗口为0时,不再接收正常数据,但是可以接收零窗口探测报文端,确认报文段,携带紧急数据的报文段。

MSS & MTU

      ** 最大报文段长度MSS**是指每一个TCP报文段中数据字段的最大长度。数据字段长度加上首部长度就等于TCP报文段的长度。

       MSS是在建立TCP连接时通信双方协商确定的。第一次握手时,发送方可以在首部中增加MSS选项,如果没有MSS选项,则MSS默认为1460字节。第二次握手时,接收方也可以在选项中增加MSS选项,最终MSS的值取连接双方声明的MSS中最小值。

       TCP数据报的MSS受限于网络层的最大传输单元MTU。如果数据链路层使用以太网的话,最大传输单元MTU为1500字节,IP数据报首部最少为20字节,TCP数据段首部至少为20字节,那么MSS最大为1460字节。如果数据链路层使用互联网,那么MTU=576字节,MSS最大为536字节。

       如果在网络层(即加上首部后)传输的数据大于MTU,TCP会在发送端将应用程序交付的数据进行分片,然后在接收端的网络层进行组合。如果其中任何一个分片产生错误,都会导致整个TCP报文段重传。分段之后的数据往下交付不会超过MTU,可以避免网络层对TCP数据进行分片。

        UDP不像TCP那样进行数据分段,UDP会将应用程序交付下来的整个数据封成一个数据报,如果数据报大小超过MTU,则由网络层进行分片。

拥塞控制

拥塞控制是指防止过多的数据注入网络中,这样可以使网络中路由器或者链路不致过载。现在通信线路的传输质量一般都很好,因传输出现差错丢弃分组的概率很小。因此,判断网络拥塞的依据就是出现了超时

TCP进行拥塞控制常用的算法有四种:慢启动&拥塞避免,快重传&快恢复

1.慢启动

TCP为发送方维持一个拥塞窗口,记为cwnd拥塞窗口是发送方使用的流量控制,接收方声明的接收窗口是接收方使用的流量控制。发送方的发送窗口大小等于这两个窗口中的最小值。

拥塞窗口的值跟MSS有关,MSS为发送的最大报文段长度旧的规定是拥塞窗口的初始值为1至2个MSS,RFC 5681规定拥塞窗口的初始值不超过2至4个MSS。

慢启动算法规定:

开始发送报文段时,把拥塞窗口cwnd设置为一个最大报文段MSS的数值。试探一下网络的拥塞情况。

每经过一个传输轮次,拥塞窗口cwnd就加倍

2.拥塞避免

慢启动算法除了维持拥塞窗口cwnd变量之外,还维持另一个变量慢启动门限ssthresh。当cwnd以指数增长的形式增长到大于或等于ssthresh时,就不再采用慢启动算法,而是采用拥塞避免算法来进行拥塞控制。

拥塞避免算法规定:

每经过一轮传输,将cwnd增加一个MSS

当拥塞发生时(超时或收到重复确认),cwnd被设置为1个MSS,ssthresh被设置为当前窗口大小的一半,但最少为两个报文段

3.快重传

如果个别报文段在网络中丢失,网络并没有发生拥塞,这种情况下发送方收不到确认报文,在超时后会重传该报文。发送方误以为发生网络拥塞,错误的开始慢启动算法,降低了传输效率。

采用快重传算法可以让发送方尽早知道个别报文段的丢失。快重传算法要求接收方不要延时发送确认,即使收到失序的报文段也要立刻发送对已收到报文的重复确认

接收方收到M1之后发送对M1的确认报文,M2报文丢失,之后接收方收到M3、M4、M5时每次都发送对M1报文的重复确认。

快重传算法规定当收到三次重复确认后,发送方就认为M2报文段丢失,立即重传M2报文段,而不用等待超时再重传,这样可以避免发送发误以为网络发生拥塞。使用快重传可以使整个网络的吞吐量提高约20%。

4.快恢复

在快重传算法执行后,发送方知道只是丢失个别报文,而不是发生网络拥塞。之后并不会执行慢启动算法,而是执行快恢复算法

把拥塞窗口和慢开始门限都设置为当前拥塞窗口的一半。然后执行拥塞避免算法,使拥塞窗口线性增大。