[图解TCP/IP]TCP与UDP

TCP(Transmission Control Protocol)与UDP(User Datagram Protocol)是传输层中两个主要协议。

TCP与UDP区别

TCP是面向连接的,可靠的流协议,通过检验和,序列号,确认应答,重发控制,连接管理以及窗口控制等机制实现可靠性传输。TCP更多应用在对数据安全有要求的场景。

UDP是不具有可靠性的数据报协议。UDP只会负责把数据发送出去,并不负责数据是否有接受对象。通常情况下,UDP主要应用于那些对高速传输和实时性有较高要求的通信和广播通信。如IP电话,视频,语音聊天等,即使丢失部分数据,也并无大碍。

UDP的特点及其目的

UDP不提供复杂的控制机制,利用IP提供面向无连接的通信服务。并且它是将应用程序发来的数据在收到的那一刻,立即按照原样发送到网络上的一种机制。

UDP面对网络拥堵的情况下,无法进行流量控制等避免网络拥塞的行为。
UDP在传输过程中即使丢包,也不负责重发。
UDP并不会调整包到达接受端的顺序,当数据包出现乱序时,需要使用UDP的应用程序自行管理。

UDP主要应用于:
这里写图片描述

TCP的特点及其目的

与UDP相比,TCP是一种面向有连接的协议,只有在确认通信对端存在是才会返送数据,从而可以控制通信流量的浪费。
TCP通过检验和,序列号,确认应答,重发控制,连接管理以及窗口控制等机制实现可靠性传输。

TCP通过序列号保证数据的可靠

在TCP中,当发送端的数据到达接受主机时,接收端主机会返回一个已收到消息的通知,这个消息叫做确认应答(ACK)。(ACK (Acknowledgement)即是确认字符,在数据通信中,接收站发给发送站的一种传输类控制字符。表示发来的数据已确认接收无误。)
TCP通过ACK实现可靠的数据传输。
这样,TCP就能通过ACK实现可靠的数据传输。
ACK通常通过序列号来确定。
序列号是按顺序给发送数据的每一个字节(8位字节)都标上号码的面好,接受端查询接收数据TCP首部中的序列号和数据的长度,将自己下一步应该接受的序号作为应答返回给发送端。通过序列号和确认应答号,TCP就可以实现可靠传输。
序列号的确认
序列号与确认应答号
通常有两种情况会导致ACK接收不正常,为了避免丢包,就引入了重发机制进行管理。

TCP以端为单位发送数据

在建立TCP链接的同时,往往胡确定发送数据包的单位,我们将其称为“最大消息长度”(MSS:Maximum Segment Size)。最理想的情况正好是IP中不会被分片处理的最大数据长度。
TCP在传送大量数据是,是以MSS的大小将数据进行分割发送,进行重发时也会以MSS为单位。
确认MSS

利用窗口提高传输速度

前面提到TCP以MSS为单位进行传输,为确保数据的可靠性,每次发送一个包就会进行一次确认应答,这样做虽然能确保数据可靠无误,但是会降低通信性能。
一个包一次应答
为了解决这个问题,TCP引入了窗口,此时确认应答不再是以每个分段,而是以更大的单位进行确认,这样会大幅度缩短转发时间。
这个机制实现使用了大量的缓冲区。例如发送端A拥有自己的发送缓冲区,同样接收端B也拥有自己的接收缓冲区。当数据从A到B传输时,B没办法一次接收所有数据,所以先把数据存入缓冲区,然后再写入设备中。所以限制了A每次发送分段制定数量的字节数。这样就确认了窗口的大小。
下图时窗口工作流程,下面会介绍更细分的窗口控制。
窗口的操作流程
(注:窗口流程介绍转载自大师带你了解TCP基本功之滑动窗口
如果我们在任一时间点对于这一过程做一个“快照”,那么我们可以将TCP buffer中的数据分为以下四类
1. 已发送已确认
数据流中最早的字节已经发送并得到确认。这些数据是站在发送设备的角度来看的。如下图所示,31个字节已经发送并确认。
2. 已发送但尚未确认
已发送但尚未得到确认的字节。发送方在确认之前,不认为这些数据已经被处理。下图所示14字节为第2类。
3. 未发送而接收方已Ready 设备尚未将数据发出
但接收方根据最近一次关于发送方一次要发送多少字节确认自己有足够空间。发送方会立即尝试发送。如图,第3类有6字节。
4. 未发送而接收方Not Ready
由于接收方not ready,还不允许将这部分数据发出。
窗口的四类划分
发送窗口与可用窗口:
整个过程关键的操作在于接收方允许发送方一次能容纳的未确认的字节数。这称为发送窗口,有时也称为窗口。该窗口决定了发送方允许传送的字节数,也是2类和3类的字节数之和。因此,最后两类(接收方准备好而尚未发送,接收方未准备好)的分界线在于添加了从第一个未确认字节开始的窗口。本例中,第一个未确认字节是32,整个窗口大小是20。
可用窗口的定义是:考虑到正在传输的数据量,发送方仍被允许发送的数据量。实际上等于第3类的大小。左边界就是窗口中的第一个字节(字节32),右边界是窗口中最后一个字节(字节51)。概念的详细解释看下图。
发送窗口与可用窗口
可用窗口字节发送后TCP类目与窗口大小的改变:

当上图中第三类的6字节立即发送之后,这6字节从第3类转移到第2类。字节变为如下:

  1. 已发送已确认字节1至31。

  2. 已发送但尚未确认字节32至51。

  3. 未发送而接收方已Ready字节为0。

  4. 未发送而接收方Not Ready字节52至95。

    确认处理以及窗口缩放:

过了一段时间,目标设备向发送方传回确认信息。目标设备不会特别列出它已经确认的字节,因为这会导致效率低下。目标设备会发送自上一次成功接收后的最长字节数。

例如,假设已发送未确认字节(32至45)分为4段传输:32-34,35-36,37-41,42-45。第1,2,4已经到达,而3段没有收到。接收方只会发回32-36的确认信息。接收方会保留42-45但不会确认,因为这会表示接收方已经收到了37-41。这是很必要的,因为TCP的确认机制是累计的,只使用一个数字来确认数据。这一数字是自上一次成功接收后的最长字节数。假设目标设备同样将窗口设为20字节。

当发送设备接收到确认信息,则会将一部分第2类字节转移到第1类,因为它们已经得到了确认。由于5个字节已被确认,窗口大小没有改变,允许发送方多发5个字节。结果,窗口向右滑动5个字节。同时5个字节从第二类移动到第1类,5个字节从第4类移动至第3类,为接下来的传输创建了新的可用窗口。因此,在接收到确认信息以后,看起来如下图所示。字节变为如下:

  1. 已发送已确认字节1至36。

  2. 已发送但尚未确认字节37至51。

  3. 未发送而接收方已Ready字节为52至56。

  4. 未发送而接收方Not Ready字节57至95。
    这里写图片描述
    处理丢失确认信息
    但是丢失的42-45如何处理呢?在接收到第3段(37-41)之前,接收设备不会发送确认信息,也不会发送这一段之后字节的确认信息。发送设备可以将新的字节添加到第3类之后,即52-56。发送设备之后会停止发送,窗口停留在37-41。
    TCP包括一个传输及重传的计时机制。TCP会重传丢失的片段。但有一个缺陷是:因为它不会对每一个片段分别进行确认,这可能会导致其他实际上已经接收到的片段被重传(比如42至45)。

TCP在丢包时有重发控制

ACK接收不正常一般有两种原因,一种是发送端发送的报文丢失,另一种是接收端返回的ACK丢失。TCP有两种机制,一种是无窗口下的超时重发机制,另一种是有窗口控制下的高速重发机制。这两种机制都对上述的两种原因有应对方法。

在无窗口下的重发控制

发送端丢包

超时重发1

ACK丢失

超时重发2
通过上述两张图片可以看出无窗口模式下的重发机制。即等待一段特定的时间间隔,然后重新发送数据。那么问题来了,为了提高速度,这个超时重发的具体时间长度有如何确定呢?
TCP对每次发包时都会计算往返时间及其偏差。为了避免丢包,重发时间就是比往返时间家偏差总和要稍大的时间。
c重发时间

在窗口控制下的重发机制

1.ACK丢失
ACK丢失
前面介绍了窗口以更大的段为单位发送数据,所以少部分丢失并无大碍。
2.发送端丢包
这里写图片描述

TCP对次序乱掉的分包进行顺序控制传递

(转载自TCP是如何保证包的顺序传输?
主机每次发送数据时,TCP就给每个数据包分配一个序列号并且在一个特定的时间内等待接收主机对分配的这个序列号进行确认,如果发送主机在一个特定时间内没有收到接收主机的确认,则发送主机会重传此数据包。接收主机利用序列号对接收的数据进行确认,以便检测对方发送的数据是否有丢失或者乱序等,接收主机一旦收到已经顺序化的数据,它就将这些数据按正确的顺序重组成数据流并传递到高层进行处理。
具体步骤如下:
(1)为了保证数据包的可靠传递,发送方必须把已发送的数据包保留在缓冲区;

(2)并为每个已发送的数据包启动一个超时定时器;

(3)如在定时器超时之前收到了对方发来的应答信息(可能是对本包的应答,也可以是对本包后续包的应答),则释放该数据包占用的缓冲区;

(4)否则,重传该数据包,直到收到应答或重传次数超过规定的最大次数为止。

(5)接收方收到数据包后,先进行CRC校验,如果正确则把数据交给上层协议,然后给发送方发送一个累计应答包,表明该数据已收到,如果接收方正好也有数据要发给发送方,应答包也可方在数据包中捎带过去。

最后介绍三种控制:流控制,拥塞控制,Nagle算法

流控制

发送端根据自己的实际情况发送数据,但是接收端可能收到一个对自己来说毫无意义同时需要花费时间处理的数据包。接受数据包过多,就会引发高负荷,此时无法再接受任何数据。当接收端不得不丢弃自己本该接受的数据时,又会触发重发机制。
因此我们需要引入流机制——让发送端根据接受端的实际接受能力控制发送的数据量。
这里写图片描述

拥塞控制

有了TCP的窗口控制,收发主机不在以一个数据段为单位发送确认应答,同时能够连续发送大量的数据包。
但是,如果在通信刚开始时就发送大量的数据,也可能会引发其它问题。
TCP为了防止这些问题的出来,在通信开始时就会通过一个叫做慢启动算法来对数据的发送量进行控制。
这里写图片描述

Nagle算法

转载自TCP-IP详解:Nagle算法
在使用一些协议通讯的时候,比如Telnet,会有一个字节字节的发送的情景,每次发送一个字节的有用数据,就会产生41个字节长的分组,20个字节的IP Header 和 20个字节的TCP Header,这就导致了1个字节的有用信息要浪费掉40个字节的头部信息,这是一笔巨大的字节开销,而且这种Small packet在广域网上会增加拥塞的出现。
Nagle算法主要是避免发送小的数据包,要求TCP连接上最多只能有一个未被确认的小分组,在该分组的确认到达之前不能发送其他的小分组。相反,TCP收集这些少量的小分组,并在确认到来时以一个分组的方式发出去。

猜你喜欢

转载自blog.csdn.net/hhmy77/article/details/80149070