传输层TCP/UDP协议详解

1,041 阅读9分钟

传输层概述

传输层负责向应用层提供通信服务,在它之下是网络层。传输层和网络层的明显区别在于,网络层负责规定主机之间的通信规则,传输层规定的是进程之间的通信规则(又叫做端到端的通信).传输层存在的意义在于,通信的真正端点并不是主机而是主机中的进程,如下图。

传输层的复用和分用

传输层有一个重要的功能就是复用和分用。

复用

就是所有应用层的进程都可以通过传输层再传送到IP层(网络层)

分用

就是传输层从IP层(网络层)接收到发送给本主机应用的数据后,负责分别交付对应的各应用进程

实现分用的方法就是我们常说的使用服务器端口号,注意这个端口实际上是软件端口,非硬件端口。只要发送方负责把报文传送到接收方某个合适的端口,剩下的交付应用进程的任务就交给TCP、UDP来完成。也就是说,两个计算机中的进程要互相通信,要明确对方的IP地址和端口号Port

传输层有两个主要的协议:TCP和UDP,下面就简单的介绍一下两种协议各自的特点

UDP协议

UDP协议是不面向连接的服务,即传送数据之前不需要先建立连接。是不可靠传输的协议,特点是:

  • 不可靠传输,速度快
  • 差错检验(但不纠错)
  • 首部开销小(8个字节)
  • 面向报文的传输
  • 可以一对多、多对多传输

UDP首部格式

如图分为:伪首部,源端口号,目的端口号,UDP数据报长度,校验和

其中,伪首部仅仅是在传输层构造用于计算校验和的作用,既不向下层传递也不向下层传递

校验和的计算方法

把所有内容:首部+数据 都进行计算

如上图,把所有的数据进行求和计算,(如果超过16位就进行回卷,即如下图,最高位的1拿到最后一位与原来的16bit进行相加,得到结果)然后把求和结果取反码就是校验和

在接收方收到数据时,接收方只需计算所有数据的和,如果16bit全为1,则表示无差错 (为什么全为1,因为发送方的校验和在计算时把和的结果取反码,并且加到了首部中,那么接收方求和就是把和的结果 加上 和的结果的反码 = 1111……(16位)

面向报文

面向报文的传输方式是,应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。若报文太长,则到达IP层需要分片,降低效率。若太短,则传输效率会下降(举个例子,1字节的数据,加上20字节的UDP首部,再加上20字节的IP层首部,结果发了41字节的包只完成了1字节有用数据的交付)。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。这也就是说。

TCP协议

TCP协议是面向连接的服务,特点是:

  • 可靠传输,速度较UDP慢一些
  • 差错检验
  • 按序交付
  • 流量控制
  • 拥塞控制
  • 首部开销大(至少20个字节)
  • 面向字节流的方式传输
  • 只支持一对一传输

面向字节流

面向字节流传输,应用程序交给TCP的是一次一个数据块(大小不等),TCP把它看成是一连串的无结构的字节流。TCP自行缓冲保存,当应用程序传送的数据块太长,TCP就可以把它划分短一些再传送。如果应用程序一次只发送一个字节,TCP也可以等待积累有足够多的字节后再构成报文段发送出去

可靠传输

需要明确的是,TCP的可靠传输是建立在网络层IP协议的不可靠传输之上的,TCP协议要采取适当的手段才能保证传输的可靠性。

这里有一个问题:TCP在传输层的可靠性和链路层保证的可靠性有什么区别,为什么我们还要再次保证可靠性呢?

直接的区别就是:链路层保证的可靠性是保证数据在数据链路上的传输无误,保证正确再向上层递交,传输层的可靠性是保证数据要到达应用层的最后一刻是正确的。 其中有一种可能性就是,到达链路层的数据是正确的,但是往上到网络层出现了错误,所以传输层就负责来纠正网络层的错误。

TCP首部格式

如上图,简要的介绍各个部分的作用

  1. 确认号:期望收到对方下一个报文的第一个数据字节的序号。即已收到的报文段序号+已收到的报文数据长度 + 1 = 确认号
  2. 数据偏移:指明报文中的数据部分距离报文首部(从零开始)有多远
  3. 保留位:暂时不作规定,默认为0
  4. URG:表示紧急情况,要最优先处理(常用于某些数据的撤销),在接收方窗口大小为0时也可以发送
  5. ACK:表示确认,只有当ACK=1时确认号字段才有效,规定建立连接之后传送的所有报文都需要把ACK=1
  6. PSH:表示推送,TCP发送端应该立即创建一个报文段发送,接收方应该尽快交付给应用进程。不应该等多个数据到了才一起递交
  7. RST:表示复位,在主机崩溃的情况下,释放连接。或者用于拒绝非法报文
  8. SYN:表示同步,用于请求建立连接或者接受连接
  9. 窗口:表示接收方告知发送方最大接受的数据量,通常小于接收方的缓存空间
  10. 紧急指针:指出紧急数据的末尾在报文段中的位置。
  11. 选项:最长为40字节,可加入报文段的数据字段最大长度MSS(指定TCP向IP层递交数据的最大长度,其大小应该使得传输尽量多的数据同时又使得IP层不需要再次分片)、窗口扩大选项(原本窗口大小为16位2进制,现在最多可以在补充14位,达到30位2进制)、时间戳(用于计算RTT和处理序列号超过2^32绕回0出现原本序号重复的问题)

滑动窗口

滑动窗口是以字节为单位的,发送方和接收方各有一个窗口,接收方通过 TCP 报文段中的窗口字段告诉发送方自己的窗口大小,发送方根据这个值和其它信息设置自己的窗口大小。

发送窗口内的字节都允许被发送,接收窗口内的字节都允许被接收。窗口外的字节不可发送。如果发送窗口某个字节已经发送并且收到了确认,那么就将发送窗口向右滑动到第一个处于未确认状态的字节;接收窗口的滑动类似,接收窗口左部字节已经发送确认并交付应用程序,就向右滑动接收窗口。(注意:如果是确认接收但未交付应用程序的字节,还会留在窗口内)

窗口和缓存之间的关系

缓存通常都要比窗口设置的值要大一些,如下图

发送缓存存放:

  1. 发送应用程序传送给下层TCP准备发送的程序(即未进入发送窗口的数据)
  2. TCP已发送但未确认的数据

接收缓存存放:

  1. 按序到达的、但尚未被应用程序接收的数据
  2. 接受应用程序
    所以缓存的大小也会影响到滑动窗口的工作。

超时重传时间的选择

(待补充)

流量控制

是滑动窗口协议的具体应用。通过接收方返回的 ACK 中所包含自己接收窗口的大小来控制发送方的数据发送。

如何控制TCP发送报文的时机?

捎带确认

当用户(应用层)只发送1个字节时,应该尽量使用捎带确认的方法

Nagle算法:

纳格算法的工作方式是合并一定数量的输出数据后一次提交。特别的是,只要有已提交的数据包尚未确认,发送者会持续累积直到一定数量的数据才提交。并且任意时刻,最多只能有一个未被确认的包

if有新资料要传送
   if窗口大小>= MSS and可传送的资料>= MSS
     立刻传送
   else
    if管线中有尚未确认的资料
      在下一个确认(ACK)封包收到前,将资料排进缓冲区伫列
    else
      立即传送

延迟确认

和Nagle算法思想是一致的

接收方收到数据包以后如果暂时没有数据要发给对端,它可以等一段时再确认。如果这段时间刚好有数据要传给对端,ACK就随着数据传输,不需要单独发送一次ACK。如果超过时间还没有数据要发送,也发送ACK,避免发送方以为丢包

糊涂窗口综合征

糊涂窗口综合症的成因
  1. 当客户端每次只能生成1个字节(传输效率低)
  2. 当服务器一次只能消耗1个字节(传输效率低)
解决方案
  1. 如果糊涂窗口综合症是由发送方产生,则Nagle算法发挥作用: 要求发送方累积到最大大小段(MSS)或者收到接收方的一个确认就发送新数据。
  2. 如果糊涂窗口综合症由接收方产生,则Clark算法发挥作用:关闭窗口,直到缓存空间已能放入具有最大长度的报文段,或者缓存空间的一半已经空了

拥塞控制

(待补充)

参考: 1.计算机网络(第七版)-谢希仁

2.zh.wikipedia.org/zh-cn/納格算法