第六章 传输层-Transport Layer(下)

上一篇文章对传输层的寻址方式、功能、以及流量控制方法做了简短的介绍,这一部分将介绍传输层最重要的两个实例:TCP协议和UDP协议,看一看之前描述的传输层要素是如何应用于TCP、UDP协议之中,并实现他们各自特点的。这一章中,读者应该重点关注TCP与UDP的区别,以及TCP是如何实现滑动窗口、拥塞控制的。

6.4 Internet传输协议:UDP/User Datagram Protocol

6.4.1UDP特点

上图是UDP的头。UDP的头很短,只包含源和目标端口号、长度和校验和四个项。

  • UDP是一种无流控、无连接、不可靠的报文流(对比TCP)
  • 目标端口号一共有16位长,用于区分不同进程
  • UDP没有包括流量控制、拥塞控制或者是重传机制。所有的这些都需要用户进程自己完成。而UDP本身只是提供了一个与IP协议的接口。
  • UDP伪头:是一个虚拟的数据结构,不是UDP头中的实际部分。伪头的存在主要是为了计算校验和,保证到达的UDP包确实是发送给自己的(因为UDP头中只含有端口信息,并没有IP地址)。这么做的原因详见6.6Faq。TCP和UDP都有伪头

下面介绍两个使用了UDP的经典协议。

6.4.2 远程过程调用:Remote Produce Call

  • 允许一台计算机上的进程调用另外一台计算机上的进程
  • 是一个分布式C-S系统的例子

6.4.3 实时传输协议: Realtime Transport Protocol

  • 应用于多媒体应用,如网络电台、视频会议RTP的头设有一个序号(Sequence Number)字段,解决了UDP发送无序的问题
  • RTP位于应用层,但是使用了UDP的传输协议

6.5 Internet传输协议:TCP/ Transport Control Protocol(重要!)

终于到了本章最后一个也是最重要的部分:TCP协议。我们之前已经简述了三次握手、AIMD等基本概念,下面将深入的展开这些概念,并明白他们是如可确保TCP连接可靠性的。

  • TCP是一种可靠的面向连接端对端的字节流(Bytestream)(对比UDP)

6.5.1 TCP服务类型

  • TCP连接是全双工的、不支持组播或者广播
  • TCP的连接是字节流,意味着不保留消息的边界

6.5.2 TCP报头(head)

注意关注TCP报头的以下几个字段:

  • 序号sequence number:用来进行排序,保证数据内容有序

  • 序号+确认号:为TCP滑动窗口服务(稍后会提到)

  • TCP头长度TCP header length:标记TCP头具有多少个32位信息,以区分报头和载荷(由于TCP头有两个位置是可选长度,故不确定长度)

  • 校验和CheckSum:用于差错控制,保证可靠性,也有IP伪头

  • 8位标志位:SYN用于建立连接;ACK是确认;FIN是释放连接;CWR与ECE用于拥塞控制

  • 窗口大小:用于流量控制(滑动窗口)

6.5.3 TCP连接建立

TCP连接建立使用的即是我们之前描述的“三次握手”的过程。注意明确两个主机之前各自的SEQ和ACK序号是怎么确定的。

6.5.4 TCP连接释放

TCP的连接释放属于对称释放,记成“四次握手”

由主机1发送一个断开连接请求,表示内容已经传送完毕,主机2确认。主机2随后也发送一个断开连接请求,主机1确认后连接正式断开。

6.5.5 TCP滑动窗口

我们在之前已经讲过了链路层的滑动窗口。而在传输层,TCP的滑动窗口是依靠TCP报头中的序号字段和确认号字段实现的。通过滑动窗口,TCP可以合理的调整发送的流量,减少拥塞现象的发生。下面用图片来解释。

假设接收方拥有一个大小为4kb的缓冲区。传输层每次接收到消息之后就会发送至这个缓冲区,同时系统也会以另一个速率从缓冲区读取信息。流量控制的目的就是维持一个合适的速率使得整个缓冲区既不溢出也不会浪费资源。此时连接已经建立,由发送方先开始发送数据。每次收到数据后,发回的ACK都包含一个字段提示自己的缓冲区余量。如果缓冲区已满,发送端就会将自己阻塞一段时间。

这里需要特别注意的还是ACK与SEQ字段大小该如何设置。SEQ字段只属于发送端,其含义大概可以理解为“已经发送了多少数据”,因此其大小等于上一个数据包中收到的ACK大小;而ACK表示的是“已经接受了多少数据”,其大小等于上一个发送端发来的数据包序列号+本次收到的数据大小。

此外,降低TCP性能的另一个原因是低能窗口综合症。当接收端每次只能读取很少的字节(假如在上面这个例子中,接收方每次刚刚读取了0.5k之后就通知发送方),整个系统会产生大量的冗余信息。解决的方法是强制接收方在有了一定大小的空间之后再通知对方。

6.5.6 TCP计时器管理

这一部分的内容主要是关于如何设置一个合适的时间界限判断数据包是否应该由于超时而被丢弃。

通过上图我们可以看到,再数据链路层中(左图),数据包到达的时间的概率密度函数相对比较集中,因此很容易设置一个界限来判断是否超时;但是在网络层下数据包到达的时间则更加分散,很难设置一个判断标准。解决的方法是使用一个依据网络情况的动态算法。

6.5.7 TCP拥塞控制(重要!)

首先简短回忆一下:网络层检测到拥塞后,会通过丢弃数据包来缓解拥塞。在传输层,我们可以使用AIMD控制法来优化网络容量。TCP的拥塞控制就以AIMD为基础,并加以改进。

拥塞窗口

TCP维护了一个拥塞控制窗口CWND-congestion window,窗口大小是任意时刻,发送端可以向网络发送的字节数。通过使用窗口大小/连接的往返时间,可以得到发送速率。TCP根据AIMD规则调整CWND大小。除此之外,TCP本来就有一个流量控制窗口RWND,指出了接收端可以接受的最大字节数,TCP最终的可能发送字节数就是两个窗口中的最小值。

相比起存放在报头中的RWND,CWND窗口维持在发送端本地,不会随着数据包发送。

确认时钟

确认时钟作用在之前讲道德CWND上,其目的是提供一个可靠的发送速率。根据观察,人们得出:确认返回到发送端的速率恰好是数据包通过路径上最慢链路的速率,这个时序就是确认时钟。通过使用确认时钟,数据包不会拥塞链路上的任意一个路由器,使得TCP能够平滑输出流量并且避免不必要的路由器队列。

慢速启动-slow start

之后的几个问题研究的是如何维持一个合适的CWND。尽管AIMD规则提供了一个比较好的思路,但是假如CWND从一个很小的规模就开始应用AIMD,则需要很长的时间才能收敛至最优点。人们因此提出了快速启动的观点:每一个被确认的段允许发送两个段,每经过一个往返时间,拥塞窗口增加一倍。

图中,RTT表示往返时间。如果数据包在一个往返时间内收到,那么表示当前的网络状况为通畅。慢速启动方式其实并不慢,CWND窗口的增长是指数级的。但相比之前的做法(直接发送RWND窗口大小的数据作为开始点),慢速启动又相对的慢一些。此外,还有必要为慢速启动设置一个慢速启动阈值一旦超出了阈值,TCP就会从慢速启动切换到线性增加-additive increase(也就是我们在AIMD中学到的知识)。在每一个RTT末尾,发送端额外注入一个数据包。

快速重传-fast retransmission

慢速启动的缺陷是必须设置一个更加保守的超时判断时间来防止因重复数据包太多导致的网络拥塞,因此可能会降低网络效率。使用重复确认(duplicate ack)机制可以部分解决这个问题:当丢失数据包的后续数据包到达接收端时,他们所触发的返回确认全部拥有相同的确认号。当发送方收到多个确认号相同的数据包后,那么就可以推断出某个数据包已经丢失(或者至少是超时)。

在TCP中,这个重复确认的数量通常被设置成3。当收到了三个连续的重复确认,发送端默认这个包已经超时,直接重新发送这个数据包(在判断超时的计时器结束之前),这么一来就缩短了等待时间。这种方法叫做快速重传。当重新发送之后,发送端会把自己的CWND阈值设置为之前CWND值的一半,并从0开始慢速启动。

如上图,慢速启动的第一个阈值被设置成32KB,并在CWND=40时发生丢包现象。丢包被检测到之后,确认时钟停止;新的阈值被设置为40KB 的一半-->20KB;重新从0开始,执行慢速启动。这是一种阶梯状的模式。

快速恢复-fast recovery

快速恢复是一种新的机制,用于确保拥塞窗口上能够持续运行确认时钟。也就是说,除非是第一次启动,其他时候不会进入慢速启动,而是直接从阈值开始线性递增。这是一种锯齿状的模式。

现在重新观察TCP拥塞控制的这张图片不难发现,其实线性递增部分就是对应着上一篇博文AIMD中的加法递增部分,而快速恢复机制对应了AIMD中的乘法递减部分(乘以1/2)。只不过上一篇中的AIMD图像表现的是两个发送端的流量变化关系,而上图表现的是一个客户端的流量随着时间的变化关系(时间是横坐标)。

6.6 TCP与UDP区别比较

TCP UDP
TCP面向连接,提供可靠的服务。
意味着TCP会使用校验和确保数据正确,使用序号确保数据有序到达且不重复,使用ACK机制重新发送丢失的数据包,并且包含连接建立和断开的过程。
UDP提供的是无连接的服务,并不可靠。
UDP不包含序号和ACK重传等机制。(当然,当应用层拥有一些特殊需求时,UDP也可以调整自己的格式以提供一些特殊服务,例如实时传输协议RTP)
TCP具有拥塞控制的功能,使用改进的AIMD规则来减少拥塞 UDP没有拥塞控制,当网络层出现拥塞时,也不会使得源主机的发送速率降低。
TCP连接只支持单播,一定是点到点的。 UDP可以进行单播、多播、广播。
TCP使用字节流,不保留消息边界。当数据过大的时候会进行拆分。 UDP面向报文流,会保留应用层提供的消息边界。
TCP的首部更长,传输速度相对较慢 UDP的首部较短,传输速度也更快。

另外关于报文流和字节流,下图可以更方便理解。

假如应用层提供了一个2048字节大小的数据等待发送,TCP可能会将其拆分成4个512字节大小的数据段,分别发送给网络层,接收方再负责组合。真正发送的数据包并不是应用层的数据,因此称为没有保留消息边界。

再来看另外一个例子,当客户分别发出32B和64B的包,流式的如TCP发送时是将32B+64B=96B的一个包发出,另一边收到的也是96B的包,TCP不再保留原来数据包的边界,而是根据协议的需求将数据统一发送;而对于UDP来说,服务器端收到的就是32B和64B的两个包,保留了从前数据包的边界。当然,包大小取决于协议和网络。

6.7 FAQ 常见问题

为什么要区分网络层和传输层?

的确,传输层和网络层有诸多的相似之处,并且共同负责了包括拥塞控制在内的多个问题的解决。但是分出两个层次依旧是必要的。

一般情况下来说,传输层的代码都运行在用户的机器上,如PC机,或者服务器;而网络层的代码大部分部署在由运营商操作的路由器上。这样的差别是设计区分这两个层次的主要原因:用户对网络层并没有真正的控制权,因为他们不拥有路由器;而另一方面,路由器也没有权限在数据包发生丢失等情况后要求PC机重新发送这个数据包。

UDP和TCP为什么需要伪头(pseudoheader)?

伪头存在的目的是为了帮助传输层的进程再一次确认该数据包确实属于这个进程所在的ip地址。问题在于,为什么传输层还需要再做一遍网络层的工作呢?难道到达网络层的时候不是已经校验过IP地址的准确性了吗?理论上来讲确实是这样的。然而在实际应用中确实会发生错发的现象,网络层可能会把一个数据包发至错误位置。例如路由出错,或者是数据包的ip头被修改了(前一章中的NAT盒子就可能会引起这一点)。

传输层的校验和与链路层的校验和有什么关系?

没有什么关系。传输层的内容会被一路封装下去,成为链路层的载荷之一。而校验和是存在各自的头部,用于校验某一层的数据是否正确。比如连链路层的校验和只管链路层。当然这两层可能采取了同一种算法。

TCP和TCP/IP有什么不可告人的关系?

我们在第一章学习了TCP/IP。TCP/IP是一个协议簇(彼此相互关联的一组协议),包含了STMP、TCP、UDP、IP等等经典协议。因为其中的TCP和IP协议最具代表性,因此统称为TCP/IP。TCP/IP包含了四个层次的协议。


到此为止,本章的内容已经全部结束,在下一章中,我们将学习应用层的内容。

第七章 应用层

传输层-Transport Layer(下):UDP与TCP报头解析、TCP滑动窗口、TCP拥塞控制详解的更多相关文章

  1. 传输层-Transport Layer(上):传输层的功能、三次握手与四次握手、最大-最小公平、AIMD加法递增乘法递减

    第六章 传输层-Transport Layer(上) 6.1传输层概述 在之前的几章内容中,我们自底向上的描述了计算机网络的各个层次,还描述了一些处于不同层次下的经典网络协议(如以太网.无线局域网.或 ...

  2. 计算机网络自顶向下方法第3章-传输层 (Transport Layer).1

    3.1 概述和运输层服务 运输层协议为运行在不同主机上的应用进程之间提供了逻辑通信(logic communication)功能. 3.1.1 运输层和网络层的关系 网络层提供了主机之间的逻辑通信,而 ...

  3. 计算机网络自顶向下方法第3章-传输层 (Transport Layer).2

    3.5 面向连接的运输: TCP 3.5.1 TCP连接 TCP是因特网运输层的面向连接的可靠的运输协议. TCP连接提供全双工服务(full-duplex service). TCP连接是点对点的连 ...

  4. TCP超时重传、滑动窗口、拥塞控制、快重传和快恢复

    TCP超时重传 原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止. 影响超时重传机制协议效率的一个关键参数是重传超时时 ...

  5. TCP三次握手与四次挥手详解

    目录 TCP三次握手与四次挥手详解 1.TCP报文格式 2.TCP三次握手 3.TCP四次挥手 4.为什么建立连接需要三次握手? 5.为什么断开连接需要四次挥手? 6.为什么TIME_WAIT状态还需 ...

  6. tcp的精髓:滑动窗口

    TCP协议作为一个可靠的面向流的传输协议,其可靠性和流量控制由滑动窗口协议保证,而拥塞控制则由控制窗口结合一系列的控制算法实现.一.滑动窗口协议 关于这部分自己不晓得怎么叙述才好,因为理解的部分更多, ...

  7. TCP面试题之滑动窗口原理

    TCP 滑动窗口 作用: 1. 提供TCP可靠性:对发送的数据进行确认 2. 流量控制:窗口大小随链路变化 一.TCP窗口机制 TCP中窗口大小是指tcp协议一次传输多少个数据.因为TCP是一个面向连 ...

  8. 网络层、传输层、应用层、端口通信协议编程接口 - http,socket,tcp/ip 网络传输与通讯知识总结

    引: http://coach.iteye.com/blog/2024511 什么是TCP和UDP,以及二者区别是什么? TCP的全称为传输控制协议.这种协议可以提供面向连接的.可靠的.点到点的通信. ...

  9. 计算机网络-传输层(1)UDP协议

    UDP协议基于Internet IP协议,只提供两个基础功能: 分用/复用 分用:主机接收到IP数据报(datagram),每个数据报携带源IP地址.目的IP地址且携带一个传输层的段(Segment) ...

随机推荐

  1. 一些 git 常用的命令

    1.本地命令 查看状态 -git status 添加文件 -git add . 提交文件 -git commit -m "(comment)" 查看历史key -git reflo ...

  2. Struts2漏洞渗透笔记

    虽然这是一次失败的渗透,但是也学到不少新姿势. 目标机环境:①外网②win2012③360全家桶 一,利用Struts2终极利用工具上传一句话 jsp的一句话,有时候会出现兼容问题.比如Cknife的 ...

  3. 博客新域名www.tecchen.tech

    新年祝福 祝新的一年,大朋友实现所有梦想,小朋友健康成长- 新域名 https://www.tecchen.tech 有效期:10年 旧链接 之前的链接请自行替换为新链接地址,包括但不限于以下二级域名 ...

  4. 常见的名片尺寸如何在CorelDRAW预设

    说到名片想必大家肯定不陌生,是我们生活中随处可见的物品,也是商家宣传必不可少的印刷物料.那么名片的尺寸是多少?我们做名片的时候该如何把握好名片的尺寸呢?在CDR中有专门的名片尺寸,下面小编就为大家简单 ...

  5. 鸿蒙OS的系统调用是如何实现的? | 解读鸿蒙源码

    本文将首先带您回顾"系统调用"的概念以及它的作用,然后从经典的Hello World开始,逐行代码层层分析--鸿蒙OS的系统调用是如何实现的. 写在前面 9月10号 华为开发者大会 ...

  6. sharding事务。

    我们这么操作: 本地事务,但是会发现如果有异常两边都回滚了.看代码如下: rollback看一看: cachedConnections中缓存了2个connection. 对于每个connection调 ...

  7. web端项目如何测试

    1.是否支持各种网络 2.网络如果演示能否正常加载 3.加载时断网还能加载出来么 4.浏览时断网页面是否保持 5.是否兼容各种不同的浏览器 6.不同的浏览器加载出的页面是否一致 7.页面效果如何 8. ...

  8. vue获取微博授权URL

    1.在Vue**页面加载时动态发送请求获取微博授权url 1.1 在 components\common\lab_header.vue 中写oauth动态获取微 博授权URL // 获取微博登录地址 ...

  9. 如何有效恢复误删的HDFS文件

    HDFS是大数据领域比较知名的分布式存储系统,作为大数据相关从业人员,每天处理HDFS上的文件数据是常规操作.这就容易带来一个问题,实际操作中对重要数据文件的误删,那么如何恢复这些文件,就显得尤为重要 ...

  10. EggJS 云原生应用硬核实战(Kubernetes+Traefik+Helm+Prometheus+Grafana),提供 Demo

    介绍 这是一个关于 Egg.js 应用上云️的示例,笔者所在的大前端团队的已应用于生产. CI/CD & DevOps & GitOps & HPA 等这里暂不做讨论,因为每一 ...