UDP、TCP协议详解

TCP协议

TCP/IP运输层的两个主要协议都是互联网的正式标准,即

  1. 用户数据报协议UDP
  2. 传输控制协议TCP

在TCP/IP体系中,两个对等运输实体在通信时传送的数据单位,根据所使用的协议是TCP或UDP,分别称之为TCP报文段和UDP用户数据报。

用户数据报协议UDP

用户数据报协议UDP只在数据报服务之上增加了很少的一点功能,这就是复用和分用的功能以及差错检测的功能。UDP的主要特点是:

  1. UDP是无连接的,即发送数据之前不需要建立连接,因此减少了开销和发送数据之前的时延。
  2. UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态表。
  3. UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。
  4. UDP没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低。
  5. UDP支持一对一、一对多、多对一和多对多的交互通信。
  6. UDP的首部开销小,只有8字节,比TCP的20个字节的首部要短。

UDP的首部格式

用户数据报UDP有两个字段:数据字段和首部字段。首部字段很简单,只有8个字节,由四个字段组成,每个字段的长度都是两个字节。各字段意义如下:

  1. 源端口 源端口号。在需要对方回信时选用。不需要时可全用0.
  2. 目的端口 目的端口号。这在终点交付报文时必须使用。
  3. 长度 UDP用户数据报的长度,其最小值是8(仅有首部)。
  4. 检验和 检测UDP用户数据报在传输中是否出错,有错就丢弃。

在这里插入图片描述

传输控制协议TCP概述

TCP的主要特点

  1. TCP的面向连接连接的运输层协议。应用程序在使用TCP协议之前,必须先建立TCP连接。在传送数据完毕后,必须释放已经建立的TCP连接。
  2. 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点。
  3. TCP提供可靠交付的服务。通过TCP连接传送的数据,无差错、不丢失、不重复,并且按序到达。
  4. TCP提供全双工通信。TCP允许通信双方的应用进程在任何时候都能发送数据。
  5. 面向字节流。TCP中的“流”指的是流入到进程或者从进程流出的字节序列。“面向字节流”的含义是:虽然应用程序和TCP的交互是一次一个数据块,但TCP把应用程序叫下俩的数据仅仅看成是一连串的无结构的字节流。

TCP的连接

TCP把连接作为最基本的抽象。每一条TCP连接都有两个端点,TCP连接的端点叫做套接字(socket)或者插口。根据RFC793的定义:端口号拼接到IP地址即构成了套接字。每一条TCP连接唯一地被通信两端的两个端点(即两个套接字)所确定。

可靠传输的工作原理——ARQ

1. 无差错情况

如图a所示,无差错情况下会每发送完一个分组就停止发送,等待对方的确认。在收到确认后在发送下一个分组。

在这里插入图片描述

2. 出现差错

如图b所示,B在接受M1是检测出了差错,就丢弃M1,其他什么也不做。只有A在超过一段时间仍然没有收到确认,就会触发超时重传重新发送前面发送过的分组。

3. 确认丢失和确认迟到

如图a所示,B所发送的M1的确认丢失了。A在规定时间内没有收到确认,就会进行超时重传,B这时又收到了一个M1,这时B就会进行两个动作,第一,丢弃这个重复的分组M1,不再向上层交付。第二,向A发送确认。

确认丢失和确认迟到

但如果发生了如图b的情况,B在接收到重复的分组后仍会执行上面说的两个步骤,A收到迟到的确认则会什么也不做。

使用上诉的确认和重传机制,我们就可以在不可靠的传输网络上实现可靠的通信。

4. 信道利用率

停止等待协议的优点是简单,但是缺点是信道利用率太低。每发送一个分组我们都要等待一个RTT(往返时间)。

为了提高传输效率,发送方可以不使用低效率的停止等待协议,而是采用流水线传输。流水线传输就是发送方可以连续发送多个分组,不必每发完一个分组就停顿下来等待对方的确认。这样可使信道上一直有数据不间断地在传送。显然,这种传输方式可以获得很高的信道利用率。

在这里插入图片描述

连续ARQ协议

滑动窗口协议比较复杂,是TCP协议的精髓所在。我们只讨论连续ARQ协议最基本的概念,不涉及许多细节。

在这里插入图片描述

如图a,表示发送方维持的发送窗口,它的意义是:位于发送窗口内的5个分组都可以连续发送出去,而不需要等待对方的确认。这样信道的利用率就提高了。

如图b,表示发送方收到一个分组的确认,就会把发送窗口向前移动一个分组的位置。接收方一般采用累计确认的方式,也就是,接收方不必对收到的分组逐个发送确认,而是在收到几个分组后,对按序到达的最后一个分组发送确认,这就表示:到这个分组为止的所有分组都已正确收到。

TCP报文段的首部格式

TCP虽然是面向字节流的,但TCP传送的数据 单元却是报文段。

TCP报文段首部的前20个字节是固定的,后面有4n字节是根据需要而增加的选项。因此TCP首部的最小长度是20字节。
在这里插入图片描述

  1. 源端口和目的端口:各占2个字节,分别写入源端口号和目的端口号。
  2. 序号:占4个字节。在TCP连接中传送的每一个字节都按顺序编号。
  3. 确认号:占4字节,是期望收到对方下一个报文段的第一数据字节的序号。
  4. 确认ACK:仅当ACK=1时确认号字段才有效。TCP规定,在连接建立后所有传送的报文段都必须把ACK置1。
  5. 同步SYN:在连接建立时用来同步序号。当SYN = 1而 ACK = 0 时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应报文段使SYN = 1 和 ACK = 1.
  6. 终止FIN:用来释放一个连接。当FIN = 1时,表明此报文段的发送方的数据已发送完毕,并要求释放运输连接。
  7. 窗口:占2字节。窗口指的是发送本报文段的一方的接受窗口。窗口值告诉对方:从本报文段首部中确认号算起,接收方目前允许对方发送的数据量。总之,窗口值作为接收方让发送方设置其发送窗口的依据。

TCP可靠传输的实现

  1. 虽然A的发送窗口是根据B的接受窗口设置的,但是在同一时刻,A的发送窗口并不总是和B的就收窗口一样大(存在拥塞情况)。
  2. 对于不按序达到的数据是先临时存放在接受窗口中,等到字节流所缺少的字节收到后,再按序交付上层的应用程序。
  3. TCP要求接收方必须有累计确认的功能,这样可以减小开销。

TCP的流量控制

利用滑动窗口实现流量控制

所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接受。

如图:

在这里插入图片描述

TCP的传输效率

可以利用不同机制来控制TCP报文段的发送时机。

  1. TCP维持一个变量,它等于最大报文段长度MSS。只要缓存中存放的数据达到MSS字节时,就组装成一个TCP报文发送出去。
  2. 由发送方的应用进程指明要求发送报文段,即TCP支持的推送(push)操作。
  3. 发送方的一个计时器期限到了,这时就把当前已有的缓存数据转入报文段发送出去。

糊涂窗口综合征的解决:1.让接收方等待一段时间,2.等到接受缓存已有一般空闲的空间再发送报文

TCP的拥塞控制

拥塞控制的一般原理

在计算机网络中的链路容量(即带宽)、交换结点中的缓存和处理机等,在某段时间的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫做拥塞。

关系式:对资源的需求的总和 > 可用资源

拥塞控制与流量控制的关系密切,也存在着一些差别。所谓拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或路由器不致过载。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷,是一个全局性的过程。相反,流量控制往往是指点对点通信量的控制,是一个端到端的问题。

在这里插入图片描述

TCP拥塞控制的方法

TCP进行拥塞控制的算法有四种,即慢开始、拥塞避免、快重传和快恢复。为了集中精力讨论拥塞控制,我们假定:

  1. 数据是单方面传送的,对方只传送确认报文
  2. 接收方总是有足够大的缓存空间,因此发送窗口的大小由网络的拥塞程度来决定

慢开始、拥塞避免、快重传和块恢复

下面讨论的拥塞控制也叫做基于窗口的拥塞控制。为此,发送方维持一个叫做拥塞窗口cwnd的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口。

发送方的控制拥塞窗口的原则是:只要窗口没有出现拥塞,拥塞窗口就可以再增大一些,以便把更多的分组发送出去,这样就可以提高网络利用率。但只要网络出现拥塞或有可能出现拥塞,就必须把拥塞窗口减小一些,以减少注入到网络中的分组数,以便缓解网络出现的拥塞。

那发送方式如何知道网络发生了拥塞呢?判断网络拥塞的依据就是出现了超时。

慢开始算法就是由小到达逐渐增大拥塞窗口数值。就是将设置拥塞窗口初始值为1,每发送并接受到对应的确认后,进行第二轮次地发送并且拥塞窗口cwnd加倍。然后每经过一个传输轮次,拥塞窗口cwnd就加倍。为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量。慢开始门限ssthresh的用法如下:

  1. 当cwnd < ssthresh 时,使用上诉的慢开始算法。
  2. 当cwnd = ssthresh 时,停止使用慢开始算法而改用拥塞避免算法
  3. 当cwnd > ssthresh 时,两者都可以

拥塞算法就是让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把拥塞窗口cwnd加1.因此在拥塞避免阶段就有“加法增大”AI的特点。

在这里插入图片描述

如图所示,一开始会执行慢开始算法,当到达门限值ssthresh时,开始执行拥塞避免算法。如果此时网络出现了超时,发送方判断为网络拥塞,于是调整门限值 ssthresh = cwnd / 2 = 12,同时设置拥塞窗口 cwnd = 1 ,进入慢开始阶段(图中没有表示该情况)。如果执行当拥塞避免时出现了图中3-ACK的情况时,就是有时个别报文段会在网络中丢失,但实际网络并未发生拥塞。这时采用快重传算法可以让发送方尽早知道发生了个别报文段的丢失。快重传算法首先要求接收方不要等待自己发送数据时才进行捎带确认,即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认。快重传算法规定,发送方只要一连收到3个重复确认,就知道接收方确实没有收到报文,应当立即进行重传(即快重传),这样就不会出现超时发送方也就不会误认为出现了网络拥塞。使用快重传可以使整个网络的吞吐量提高约20%。

于是,在发生了快重传后,发送方知道现在只是丢失了个别的报文段。于是不启动慢开始,而是执行快恢复算法。这时,发送方调整门限值 ssthresh = cwnd / 2 = 8,同时设置拥塞窗口 cwnd = ssthresh = 8,并开始执行拥塞避免算法。也有的快恢复实现是把拥塞窗口设置为 ssthresh + 3 x MSS。我们也把这种称为“乘法减小”MD。与“加法增大:AI 合称AIMD算法。

以下流程图更清楚地表示以上过程:

在这里插入图片描述

发送方窗口是接收方窗口rwnd 和拥塞窗口 cwnd中数值较小的一个。

主动队列管理AQM

主队队列管理就是不要等到路由器的队列长度已经达到最大值才不得不丢弃后面到达的分组。而是在队列达到警惕长度时主动丢弃到达的分组。AQM有很多实现的方法,其中有随机早期检测RED随机丢弃。

TCP的运输连接管理

TCP是面向连接的协议。运输连接是用来传送TCP报文的。TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程。因此,运输连接就有三个阶段,即:连接建立、数据传送和连接释放。

TCP连接的建立

TCP建立连接的过程叫做握手,握手需要在客户和服务器之间三个TCP报文段,也叫做三次握手。

在这里插入图片描述

最初两段的TCP进程都处于CLOSED(关闭)状态。本例中,客户端主动打开连接,服务端被动打开连接。一开始B的TCP服务器进程先创建传输控制块TCB,准备接受客户端的连接请求。然后服务器进入LISTEN(收听)状态。A的TCP客户进程也是首先创建控制模块TCB,然后在打算建立TCP连接时,向B发出连接请求报文段,这时首部中同步位SYN = 1,同时选择一个初始序号 seq = x。TCP规定,SYN报文段(即SYN = 1的报文段)不能携带数据,但要消耗掉一个序号。这时TCP客户进程进入SYN-SENT(同步已发送)状态。

B收到连接请求报文段后,如同意建立连接,则向A发送确认。在确认报文段中应把SYN和ACK都置1,确认号是ack = x + 1,同时也为自己选择一个序列号 seq = y。请注意,这个报文段也不能携带数据,但同样要消耗掉一个序号。这时TCP服务器进程进入SYN-RCVD(同步收到)状态。

TCP客户进程收到B的确认后,还要向B给出确认。确认报文段的ACK置1,确认号ack = y + 1,而自己的序号 seq = x + 1.TCP规定,ACK报文可以携带数据。但如果不携带数据则不消耗序号,在这种情况下,下一个数据报文段的序号仍是seq = x + 1.这时,TCP连接已经建立,客户端进入ESTABLISHED(已建立连接)状态。

当B收到A的确认后,也进入ESTABLISHED状态。

以上过程就叫做三次握手。请注意,B在图中B发送给A的报文段也可以拆成两个报文段。可以先发送一个确认报文段(ACK = 1,ack = x + 1),然后再发送一个同步报文段(SYN = 1,seq = y)。这样的过程就变成了四报文握手,但是效果是一样的。

为什么A最后还要再发送一次呢?是因为防止已失效的连接请求报文段突然传送到了B,因而产生错误。

TCP连接释放

在这里插入图片描述

数据传输结束后,通信的双方都可释放连接。现在A和B都处于ESTABLISHED状态。A的应用进程先向其TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接。A把连接释放报文段首部的终止控制位FIN置1,其序号seq = u,它等于前面已传送过的数据的最后一个字节的序号加1。这时A进入FIN-WAIT-1 (终止等待1)状态,等待B的确认。请注意,TCP规定,FIN报文段即使不携带数据,它也消耗掉一个序号。

B收到连接释放报文段后即发出确认,确认号是ack=u+1,而这个报文段自己的序县是v,等于B前面已传送过的数据的最后一个字节的序号加1。然后B就进入CLOSEWAIT (关闭等待)状态。TCP服务器进程这时应通知高层应用进程,因而从A到B这个方向的连接就释放了,这时的TCP连接处于半关闭(half-close)状态,即A已经没有数据要发送了,但B若发送数据,A仍要接收。也就是说,从B到A这个方向的连接并未关闭,这个状态可能会持续一段时间。

A收到来自B的确认后,就进入FIN.WAIT-2 (终止等待2)状态,等待B发出的连接释放报文段。

若B已经没有要向A发送的数据,其应用进程就通知TCP释放连接。这时B发出的连接释放报文必须使FIN = 1。现假定B的序号为w (在半关闭状态B可能又发送了一些数据)。B还必须重复上次已发送过的确认号 ack = u + 1。这时B就进入LAST-ACK (最后确认)状态,等待A的确认。

A在收到B的连接释放报文段后,必须对此发出确认。在确认报文段中把ACK置1确认号 ack = w + 1,而自己的序号是 seq = u + 1 (根据TCP标准,前面发送过的FIN报文段要消耗-一个序号)。然后进入到TIME-WAIT (时间等待)状态。请注意,现在TCP连接还没有释放掉。必须经过时间等待计时器(TIME- WAIT timer)设置的时间2MSL后,A才进入到CLOSED状态。时间MSL叫做最长报文段寿命(Maximum Segment Lifetime)。当A撤销相应的传输控制块TCB后,就结束了这次的TCP连接。

为什么A在TIME-WAIT状态必须等待2MSL时间呢?有两个理由。

第一,为了保证A在发送的最后一个ACK报文段能够到达B。

第二,防止上一节提到的“已失效的连接请求报文段”出现在本连接中。

额外扩展

滑动窗口的作用:1.累计确认 2.流量控制 3.拥塞控制


版权声明:本文为qq_45902611原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。