计算机网络超详细笔记(六):传输层
文章目录
第六章 传输层
6.1 传输层概述
6.1.1 传输层概述
-
传输层:整个协议栈 (TCP/IP) 的核心
- 任务:提供可靠的、高效的的数据传输
-
传输实体:完成传输层任务的硬件或软件
- 可能位于:
- 操作系统内核
- 独立的用户进程
- 绑定在网络应用中的链接库
- 网络接口卡
- 可能位于:
-
传输层服务
- 面向连接的服务 (与网络层提供的服务相似)
- 无连接的服务
-
传输层提供的功能
- 端点标识
- 传输服务
- 面向连接:端到端的连接服务、流控制、差错控制
- 无连接
-
两大传输层协议
- UDP (User datagram protocol) —— 用户数据报协议
- TCP (Transport control protocol) —— 传输控制协议
6.1.2 传输层的必要性
- 为什么需要两个独立的不同的层?
- 网络层运行在由承运商操作的路由器上,因此用户无法真正控制到网络层。
- 把另一层放在网络层之上,可以让用户能够控制到服务质量。
- 传输层服务原语独立于网络层原语,而网络层原语会因为网络的不同而不同。
- 网络层与传输层作用范围比较?
-
网络层负责把数据从源机送达到目的机
-
传输层负责把数据送达到具体的应用进程
-
- 传输层:end to end,此处 end 为端点 (end point) 或套接字 (socket)
-
6.1.3 数据链路层与传输层的比较
- 功能相似
- 流控制、差错控制、数据 (报文/帧) 排序
- 传输环境不同
- 通信子网
- 点对点的物理信道 (数据链路层)
6.1.4 传输服务原语
- 传输服务原语让应用程序可以有途径访问到传输服务
- 传输服务和网络服务的两个主要差别是:
- 网络服务试图按照实际网络提供的服务来建模 (不可靠的),而面向连接的传输服务是可靠的。
- 网络服务仅被传输实体所使用,而传输服务直接被应用程序所使用,必须方便易用。
- 简单的传输服务原语
6.1.5 数据段
- TPDU (Transport Protocol Data Unit)
- 从传输实体发到对端传输实体的信息。
- TPDUs被封装在分组 (Packet) 中,由网络层交换
- 分组被封装在帧 (frames) 中,由数据链路层交换
6.1.6 课程总结
- 传输层提供什么样的服务?
- 为什么需要一个独立于网络层的传输层?
- 传输层的协议数据单元 (PDU) 是什么?
- 传输层的协议有哪些?
6.2 用户数据报协议 UDP
6.2.1 UDP 概述
- UDP 特点
- UDP是一个无连接的传输层协议
- UDP传输数据段,无须建立连接,不提供数据段的可靠传输
- 如DNS通过UDP发送一个请求,然后对方进行应答
6.2.2 UDP 数据段头
- UDP数据段包括头部和数据两个部分,其中头部有4部分,每部分2字节,共 8 字节
-
-
第一部分和第二部分分别为源端口和目的端口
-
第三部分的长度包括头部和数据总共的长度
-
校验和可选,如果不计算校验和,则该域置为 0。
-
UDP比IP好的地方在于它可以使用源端口和目的端口。
-
- 端口
- 端口共16位,共有 个端口
- 端口范围:0~65535
- 端口分为三部分
- ① ,用于公共应用 (保留,全局分配,用于标准服务器),由 IANA 分配
- ② 1024~49151,非特权用户端口,注册端口
- ③ ,动态端口,私人端口
- 自由端口
- 本地分配、动态的随机端口
- 访问网站时,网站的端口通常是一些知名端口 (比如80),而本地主机端口是系统自动分配的一个自由端口,通常 $\geq 49152 $。
6.2.3 UDP 校验和
- 校验和
-
将IP伪头部、UDP段头、数据三个部分,按照16位一行,然后按列进行补码相加求和,再将相加结果拿来取反码,作为最后的校验和。
-
-
如果收方的校验和为全 1,则传输无错
-
二进制反码求和
- 从低位到高位逐列计算
- 0和0相加是0,0和1相加是1,1和1相加是0,但产生进位
- 最高位相加产生进位,该位为 1
-
检错能力较弱,但简单快速
-
使用协议地址,破坏了分层原则
-
- TCP/UDP 伪头部
-
-
第一、二字段为源、目的IP地址
-
第四字段为用户协议,6为TCP,17位UDP
-
第五字段为UDP头部中的长度字段 (UDP头部与数据长度之和)
-
6.2.4 课程总结
- UDP 提供端点标识,端到端的数据传输
- UDP 不提供差错检测和可靠传输,但简洁高效
- UDP 是传输层的一个轻量级协议,提供高效的端到端的数据段传输
- UDP 数据段包括头部和载荷两部分,头部有8个字节,共4个字段。
- UDP 不提供数据传输的可靠保证。
- 问题
- 为什么需要 UDP?
- UDP 的段格式是怎样吗?
- UDP 提供的服务是可靠的吗?
- UDP 提供的服务可以用什么样的词来描述?
6.3 通信模型
- 通信 5 元组
- 源端点:源IP、源端口
- 目的端点:目的IP、目的端口
- 协议:UDP、TCP
- 知名端口
6.4 TCP 数据段
6.4.1 TCP 概述
- 传输控制协议 (TCP - Transmission Control Protocol)
- TCP 是专门为了在不可靠的互联网络上提供可靠的端到端字节流而设计的。
- TCP 必须动态地适应不同的拓扑、带宽、延迟、分组大小和其它的参数,并且当有错误的时候,能够足够健壮。
- 支持 TCP 的机器都有一个 TCP 实体,或者是用户进程或者是操作系统内核,都可以管理 TCP 流和跟 IP层的接口。
- 发:封装
- TCP实体接收本地进程的用户数据流,将其分割成不超过64KB的分片 (实践中,通常分割成1460字节,以通过以太网传输)
- 收:解封装
- 当包含TCP数据段的报文到达某台机器的时候,被提交给传输实体,传输实体将其重构出原始的字节流。
- 发:封装
- TCP协议
- TCP连接上的每个字节都有它自己独有的32位***
- 收发双方的TCP实体以数据段的形式交换数据
- 一个数据段包括20字节的头部 (不包括可选项) 和数据域 (0或更多字节)
- TCP软件决定数据段的大小,有两个因素限制了数据段的长度
- TCP数据段必须适合IP的 的载荷限制
- 每个TCP数据段必须适合于下层网络的MTU (如,1500字节 - 以太网载荷大小)
- TCP使用的基本协议具有动态窗口大小的滑动窗口协议
6.4.2 TCP 数据段格式 (TPDU)
-
TCP 数据段格式 (TPDU)
- 20字节的头部 (不包括可选项)、变长的数据字段/域 (可以是0个或更多字节)、不含选项的头部有14个字段/域
-
TCP 数据段头
-
第一、二个字段:源端口、目的端口
- 标明了一个连接的两个端点
- 用来跟踪同一时间内通过网络的不同会话。一般每个端口对应一个应用程序。
-
第三个字段:***
- 字节号 (32位) [当前所携带的数据的第一个字节的顺序号]
- 初始*** ISNs (initial sequence numbers):随机产生
- SYN (连接请求数据段):携带了ISNs和SYN控制位的数据段
-
第四个字段:确认号
- 期望接收的字节号 (32位)
- TCP的可靠传输保证,采用了肯定确认机制。
- 也采用了累计确认,如果确认号为500,表明收到了***小于500的所有数据段。
-
第五个字段:TCP 段头长度 (4 bits)
- 单位:4字节
-
第六个字段:保留域/字段
- 可以用来拥塞控制
- 接下来是6个控制比特位
-
第六个字段:URG
- 当紧急指针使用的时候,URG被置为 1。紧急指针是一个对于当前***的字节偏移量,标明紧急数据从哪里开始。
- 当 URG = 1 时,表明有紧急数据,必须首先处理。
- 与紧急指针配合使用。
- 收方收到这样的数据后,马上处理,处理完后恢复正常操作。
- 即使 win = 0 (告诉对方不可以发送数据),也可以发送这样的紧急数据段。(比如 ctrl+c 中断命令)
-
第七个字段:ACK
- ACK = 1,表明确认号有效,启用了捎带确认
- ACK = 0,表明确认号失效
-
第八个字段:PSH
- PSH = 1,表明这是带有PUSH标志的数据
- 接收方收到PUSH标记的数据,应该立刻送到上层,而不需要缓存它。
-
第九个字段:RST
- 重置一个已经混乱的连接
- 如果在连接建立阶段,就直接拒绝建立连接
-
第十个字段:SYN
- SYN用在连接建立的过程
- SYN = 1,ACK = 0,表明请求连接
- SYN = 1,ACK = 1,表明连接接受
-
第十一个字段:FIN
- 用来释放连接,表明发送方已经没有数据要传输了,但是可以继续接收数据。
-
第十二个字段:Window Size
- TCP中的流控使用一个可变长的滑动窗口来完成的。
- Window Size,告诉对方可以发送的数据字节数 (从确认字节号开始 - 由接收方决定)
-
第十三个字段:Checksum
- 提供额外的可靠性
- 检验的范围包括头部、数据和伪头部 (伪头部中用户协议取值为6)
-
第十四个字段:紧急指针
- 和URG控制位配合使用,指明了紧急数据
-
第十五个字段:选项域
- 提供了一种增加基本头没有包含内容的方法
-
第一、二个字段:源端口、目的端口
-
选项字段
- 允许每台主机指定他愿意接收的最大TCP净荷长度
- 窗口尺度 (Window scale) 选项允许收发双方协商一个窗口尺度因子,这个因子允许双方把窗口尺寸域向左移动至14位
- 选择性重传选项
-
例题
6.4.3 课程总结
- TCP数据段中的***是段的编号吗?
- TCP数据段中的初始***是怎样来的?
- TCP数据段中的确认号有什么用?
- TCP数据段中的窗口尺寸有何作用?
6.5 TCP 三次握手建立连接
6.5.1 TCP 连接的建立
-
采用三次握手建立连接
- 一方 (server) 被动地等待一个进来的连接请求
- 另一方 (the client) 通过发送连接请求,设置一些参数
- 服务器方回发确认应答
- 应答到达请求方,请求方最后确认,连接建立
-
TCP 连接建立图示
-
-
第一次 Host1 向 Host2 发连接请求
- 连接请求数据段:SYN = 1, ACK = 0,SEQ = x,SEQ为系统随机产生
-
第二次 Host2 向 Host1 发连接应答
- 连接应答数据段:SYN = 1,ACK = 1,SEQ = y,ACK = x+1,SEQ为系统随机产生
-
第三次 Host1 再向 Host2 发确认数据段
- 确认数据段:SYN = 0,ACK = 1,SEQ = x+1,ACK = y+1,三次握手结束,连接建立
-
-
三次握手建立TCP连接,也称为同步。这个过程中,双方交换了一个最重要的参数 —— 初始***,这个可以用来跟踪后续交换的每一个字节。即后续的字节的编号就是以这个初始***作为基础的。建立TCP连接的双方没有主从之分,它们可以相互收发数据,因此TCP数据段的传输是全双工的。
-
为什么是三次握手?
- 为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个***, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知***起始值, 并确认对方已经收到了***起始值的必经步骤。
- 如果只是两次握手, 至多只有连接发起方的起始***能被确认, 另一方选择的***则得不到确认。
6.5.2 DoS 攻击
- SYN泛洪导致DoS攻击 (伪造源IP)
- 大量 Agent 向被攻击方发送TCP请求连接数据段,但源IP伪造成一个不存在的IP
- 由于不会有主机回发确认数据段,被攻击方会挂起大量进程,最终资源耗竭而崩溃。
- 数据传输开始后可能有两个原因导致阻塞
- 快的机器向慢的机器发送数据
- 多台机器同时向一台机器发送数据
6.5.3 课程总结
- TCP连接是怎样建立起来的?
- 使用2次握手来建立TCP连接可以吗?
- 为什么TCP连接过程又叫同步?
- SYN泛洪攻击是怎样产生的?
6.6 TCP 连接释放
6.6.1 TCP 连接释放
- TCP 连接释放
- 任何一方在没有数据要传送的时候,都可以发送一个 FIN = 1 的 TCP 数据段
- 当 FIN 被确认之后,该方向的连接关闭
- 当双向连接都关闭了的时候,连接释放
- 连接释放的问题
- 连接释放取决于另一方,这导致连接释放要求连接的两端都释放,但是决定什么时候两边释放非常困难
- 最后信息的发送者,永远无法知道这个信息是否到达
- 解决方案 1
- 将释放连接的决定权交给请求者独立裁定,而不是对方。
- 比如,一方发送连接释放请求DR (Disconnect Request),且期待对方的确认ACK
- 当DR到达接收端,它回发ACK,并且也发送一个DR
- ACK到达发送端的时候,连接释放;同时,它回发确认ACK,当这个ACK到达接收端,反方向的连接也释放了。
- 将释放连接的决定权交给请求者独立裁定,而不是对方。
- 解决方案 2:使用定时器
- 如果一方发送了FIN数据段出去,却在一个设定的时间没有收到应答,释放连接
- 另一方最终会注意到连接的对方已经不在了,超时后连接释放。
6.6.2 半开放连接
- 定义
- 理论上讲,如果初始DR和重传都丢了,发送者将因超时放弃发送且释放连接。但是,另外一端却不知道这些情况,仍然处于活跃的状态。
- 这种情况导致半开放连接。(half-open)
- 杀死半开放连接的方式
- 如果在一定的时间内,没有TPDUs到达的话,连接自动释放
- 因此传输实体在发送一个TPDU的时候必须启动定时器,定时器超期,将发送一个哑TPDU,以免连接断开。
6.6.3 三次握手正常释放连接
-
正常释放连接过程
-
如果确认ACK丢失
-
TCP 4步终止会话
6.6.4 课程总结
- TCP是全双工的,连接的释放必须是双向的
- FIN = 1
- 半开半闭的连接必须杀掉
- 超时会挂掉连接
- 问题
- TCP连接是怎样释放的?
- 半开半闭的连接怎么办?
6.7 TCP 传输策略
6.7.1 Window Size 流量控制
- Window Size 流量控制具体过程
-
-
窗口尺寸由接收方决定,当WIN = 0时,发送方不能再发送数据。当接收方有流量之后,会像发送方重新发送TCP数据段,更新WIN。
-
- WIN = 0
- 当 WIN = 0 时,发送者不能正常发送数据段,除非
- Urgent数据。例如,用户想杀掉远端机器上的进程时,可以发送数据。
- 发送者可以发送一个字节的数据段,以便让接受者再次发送期待的字节号和窗口数 (避免死锁)
- 当 WIN = 0 时,发送者不能正常发送数据段,除非
6.7.2 优化发送端
- Nagle’s algorithm
- 当数据以一次一字节的速度到达的时候,只发送第一个字节,然后将后续的字节缓存起来,直到发出的字节得到确认。
- 将缓存起来的字节在一个数据段中发出,再继续缓存,直到发出的数据得到确认。
- Nagle算法在很多TCP上实现,但是有些时候最好禁用。
- 比如,当一个X-Window应用在互联网运行的时候,鼠标的移动事件必须发送给远程计算机,把这些移动事件收集起来一批一批发送出去,使得鼠标的移动极不连贯。
- Nagle 算法图示
6.7.3 优化接收端
- Clark 算法
- 阻止接收方发送只有 1 个字节的窗口更新,相反,它必须等待一段时间,当有了一定数量的空间之后再告诉发送方。
- 接收方可以维护一个内部缓冲,且阻塞上层应用的 READ 请求,直到它有大块的数据提供。
- Clark 算法图示
6.7.4 课程总结
- 发送方
- 尽量不发送数据含量小的数据段
- 缓存应用层的数据,达到一定量再发送
- 接收方
- 不请求对方发送短数据段 (window size)
- 延迟窗口变更信息,使接收缓冲区足够大
- 问题
- TCP如何进行流控?
- 怎样提高TCP传输的效率?
- TCP的发方怎样优化?
- TCP的收方怎样优化?
6.8 TCP 拥塞控制
6.8.1 TCP拥塞概述
- 分组守恒:当有一个老的分组离开之后才允许新的分组注入网络
- TCP 希望通过动态维护窗口大小来实现这个目标
- 拥塞检测
- 所有的互联网TCP算法都假定超时是由拥塞引起的,并且通过监视超时的情况来判断是否出现问题。
- 拥塞控制
- 接受者容量 (维护接收者窗口 —— 容易控制)
- 当一个连接建立的时候,双方选择一个合适的窗口大小,接收方根据自己的缓冲区大小来指定窗口的大小。
- 如果发送者遵守此窗口大小的限制,则接收端不会出现缓冲区溢出的问题,但可能由于网络内部的拥塞而发生问题。
- 网络容量 (维护拥塞窗口 —— 难于控制)
- 接受者容量 (维护接收者窗口 —— 容易控制)
6.8.2 慢启动算法 (Slow Start)
-
慢启动算法过程
- 当连接建立的时候,发送者用当前使用的最大数据段长度初始化用塞窗口,然后发送一个最大的数据段。
- 如果在定时器超期之前收到确认,则将拥塞窗口翻倍,然后发送两个数据段……直至超时 (或达到接收方窗口的大小)
- 确定出拥塞窗口的大小
- 例如,一开始发4096字节没有问题,下一次就发8192字节,如果发生超时,则拥塞窗口设为4096字节。
-
慢启动算法图示
6.8.3 阈值
-
除了使用接受者窗口和拥塞窗口,TCP拥塞控制还是用了第三个参数,阈值 (threshold),初始化为 64K。
- 当一个超时发生的时候,阈值降为当前拥塞窗口的一半,同时将拥塞窗口设为一个最大数据段的长度。
- 使用慢启动算法来决定网络的容量,拥塞窗口增长到阈值时停止指数增长。从这个点开始,每次成功的传输都会让拥塞窗口线性增长 (每次仅增长一个最大的数据段长度)
-
慢启动算法+阈值图示
-
-
一开始2倍倍增增长,到达阈值后变为线性增长。
-
线性增长到超时之后,阈值降为一半,拥塞窗口回到初始值。重复步骤。
-
-
线性增长,可以将越来越粗放的窗口尝试粒度变小,以获得更准确的拥塞窗口值。
-
TCP慢启动算法就是这样不断超时、不断重启,尝试出的拥塞窗口值也随着网络状况的变化而发生变化,达到拥塞控制的目的。
-
快速恢复
- 重新慢启动时,拥塞窗口值不用重置为一个数据段大小,而是可以设置为阈值大小,从这里直接开始线性增长,即快速恢复。此时,反复的慢启动过程呈现出一个锯齿形状。
6.8.4 课程总结
- TCP拥塞控制的原则是什么?
- 引起TCP拥塞的两种因素是什么?
- TCP怎么进行拥塞控制?
- 拥塞窗口怎么获得?
- 阈值有什么作用?
- 多次慢启动尝试,CWND是否会达到一个不变的常数?
6.9 TCP 定时器
6.9.1 重传定时器
- 为了解决数据段丢失的问题,每发一个数据段都会启动一个定时器 (重传定时器)。
- 该定时器的时间长短设置需要仔细的考量。
6.9.2 持续定时器
- 避免如下的死锁发生:
- 接收方发送了一个窗口数为0的确认 (窗口更新),告诉发送方等待。
- 稍后,接收方空出了缓存,发送更新窗口的数据段,但是该分组丢失了。
- 现在,收发双方都在等待对方发送数据段过来,但大家都等不到,由此死锁产生!
- 解决死锁的方法:
- 发送方在收到 win = 0时,启动一个持续定时器,如果定时器超期没有收到更新窗口,则发送一个探测数据段,引发对方重新发出更新窗口!
6.9.3 保活定时器
- 保活定时器 (keep-alive timer)
- 用来检查连接是否存活,当一个连接空闲的时间超过保活定时器的时间,该连接将被杀掉。
- 在关闭时刻处于timed wait状态中使用的定时器:运行两倍的最大分组生存时间,以确保连接关闭之后,该连接上的所有分组都完全消失。
6.9.4 课程总结
- TCP与UDP的比较
- 可靠性:TCP可靠,UDP不可靠
- 传播延迟:TCP不确定,UDP为网络延迟
- 拥塞控制:TCP有拥塞控制,UDP没有拥塞控制
- 选择TCP的情况
- 需要可靠传输方式
- 需要让应用程序简单化,程序员不必进行错误检查、修正等工作
- 选择UDP的情况
- 为了降低对计算机资源的需求 (DNS)
- 应用程序本身已提供数据完整性的检查机制,勿须依赖传输层的而协议来保证。
- 应用程序传输的并非关键性的数据。
- 一对多方式,必须使用UDP (视频传播) (TCP仅限于一对一的传送)
- 问题
- TCP中的重传定时器如何工作?
- TCP的持续定时器用来做什么?如何做?
- 比较UDP和TCP?
- 如何选择传输层的协议?