概述
文章目录
- 传输层
- 传输层协议概述
- 用户数据报协议 UDP
- 传输控制协议 TCP
- TCP报文段格式
- TCP 连接管理
- 连接建立
- 数据传输
- 连接释放
- TCP 滑动窗口
- TCP 流量控制
- TCP 触发传输
- Nagle算法
- TCP 丢失恢复
- 自适应重传
- Karn/Partridge算法
- Jacobson/Karels算法
- 超时重传的效率问题
- 快速重传 fast retransmit
- 时间戳 TimeStamp 选项
- TCP 拥塞控制
- TCP(端到端)的拥塞控制
- 拥塞检测
- 发送速率 (拥塞窗口大小)调整
- 慢启动 slow-start
- 拥塞窗口的增减策略
- TCP拥塞避免
- TCP拥塞控制算法
- 网络中间设备对TCP性能的影响
- 主动队列管理
- 随机早期检测 RED
传输层
网络层以及网络层的下层实现了主机到主机的通信,依靠网络完成了无连接的、尽最大努力交付的数据报传输服务。
传输层实现系统上运行的应用进程间的逻辑通信(端到端传输)
为了支持网络间的数据传输,还需要实现很多功能:
- 支持多应用进程(UDP、TCP)
- 确保消息成功传输(TCP)
- 消息按序传输(TCP)
- 允许接收方对发送方进行流量控制(TCP)
- 支持任意大的消息(TCP)
- 拥塞控制(TCP)
传输层协议概述
传输层的两个主要协议:
-
用户数据报协议 User Datagram Protocol—— 端到端的、尽力而为的数据报传输服务
简单异步多路分解与复用:所有应用进程的数据通过传输层传输到IP层,即多路复用;传输层收到的数据交付给相应的应用进程即多路分解 -
传输控制协议 Transmission Control Protocol——端到端的、可靠的、面向连接的字节流服务
① 多路分解与复用:需要用统一的方法对 TCP/IP 体系的应用进程进行标识
② 连接管理:先建立逻辑连接,进行双向数据流传输,通信结束后撤销连接
③ 可靠传输:对一个连接上传输的每个字节编号,通过接收确认和重传来保证可靠传输
④ 流量控制:防止发送方发出的数据超出接收方的接收能力
⑤ 拥塞控制:防止过多数据注入网络造成网络结点或链路超载
PS:关于传输端口的多路分解和多路分解:
传输层采用抽象定位符端口(port),使得进程间能够间接相互识别
① 源进程向源端口发送消息
② 目的进程从目的端口接收消息
③ 尽管通信的终点是应用进程,但可以把端口想象是通信的终点(只要把要传送的报文交到目的主机的相应的目的端口,剩下的工作(即最后交付目的进程)就由传输层协议来完成)
端口用16位整数标识(只对单台主机有效,进行进程的区分) -
UDP传输由**<主机IP,端口号>**二元组唯一标识
-
TCP连接由**<源端口号,源主机IP,目的端口号,目的主机IP>**四元组唯一标识
三类端口:
① 熟知端口0~1023
② 登记端口 1024~49151(提供给服务提供商使用)
③ 客户端端口 49152-65535(提供给客户端使用)
用户数据报协议 UDP
UDP:最简单、最基本的传输协议,面向报文
功能:端口的功能,差错检测的功能
特点:
① 无连接,开销小,无需维护路径和状态
② 尽最大努力交付,不保证可靠传输
③ 没有拥塞控制,就是个弱终端
④ 数据传输面向数据块的,应用层业务驱动,传输完整的报文
⑤ 可以定制实现支持高速广域网的海量数据传输(TCP在高带宽长距离网络上性能很差)
传输控制协议 TCP
TCP:面向连接的、可靠的、有序的字节流传输服务
PS:面向字节流:TCP将应用程序交付的数据看做一连串无结构的有序字节流
可靠的:可靠传输,对一个连接上传输的每个字节编号,通过接收确认和重传来保证可靠传输
点对点的双工通信:TCP连接是点对点的字节流,两端都设有缓存
TCP报文段格式
- 源端口(SrcPort)、目的端口(DstPort):各2字节,分别写入源、目的端口号
端口是传输层与应用层的服务接口,传输层多路分解/复用通过端口实现。每个TCP连接的唯一标识 <SrcPort, SrcIPAddr, DstPort, DstIPAddr> - 序号(Sequence Num):4字节
TCP 连接中传送的数据流中的每一个字节都按顺序编上一个序号,序号字段的值则指的是本报文段所发送的数据的第一个字节的序号 - 确认号(Acknowledgment Num):4字节
指期望收到对方的下一个报文段的数据的第一个字节的序号。若确认号=N,则表明:到序号N-1为止的所有数据已正确接收 - 数据偏移/首部长度 (Offset/HdrLen):4 bit
TCP 报文段的数据起始处到 TCP 报文段起始处的偏移,即头部长度。单位为32位字(4字节),最大值为60字节,选项长度不超过40字节 - URG (URGent, 紧急):置1时,标志本报文段包含紧急数据
此时紧急指针 (UrgPtr) 字段指明报文段中的非紧急数据从什么地方开始,紧急数据在报文段段体前部 - ACK (确认):仅当该标志位置1时,确认号字段才有效
表明接收方应对 确认号 字段加以注意 - PSH (PuSH, 推送):该标志位置1时,说明发送方调用了push操作
接收方应尽快地交付给接收应用进程 - RST (ReSeT, 复位):该标志位置1时,说明TCP连接出现了严重差错
必须释放连接,重新建立。也通过对该位置1,拒绝一个非法的报文段或拒绝打开一个连接 - SYN (同步):在建立TCP连接时使用,置1,表示这是一个连接请求/接受报文
SYN=1, ACK=0:连接请求
SYN=1, ACK=1:连接接受 - FIN (终止):用来释放一个连接
FIN = 1,表明此报文段的发送端的数据已发送完毕,要求释放TCP连接 - AdvertisedWindow (接收窗口):2字节,滑动窗口算法中使用,流量控制
指明该报文段发送者的接收窗口大小,用于指示对端设置其发送窗口大小 - CheckSum (校验和):2字节,与UDP中的用法相同
计算整个TCP首部部、TCP数据、伪首部(12字节)
+选项:可变长,最大40字节
最大报文段长度 MSS (Maximum Segment Size)选项、窗口扩大选项、时间戳选项、选择确认选项
各个功能实现与报文段信息对应:
- 多路复用——源、目的端口
- 连接管理——SYN、FIN、ACK、序号、确认号
- 可靠传输——ACK、确认号、选项
- 流量控制——接收窗口、选项
- 拥塞控制(未在协议格式中体现)
TCP 连接管理
连接是TCP最基本的抽象,每条TCP连接有两个端点(即套接字 socket=(IP: Port)),那么TCP连接={socket1, socket2}={(IP1: Port1), (IP2: Port2)}(唯一标识)
TCP连接管理能使TCP连接的建立和释放都能正常地进行,TCP连接有三个阶段:
连接建立
目的:
① 使每一方能够确知对方的存在
② 双方确定自己的初始序列号,并通知对端:两端的初始序列号相互独立,各自随机选择一初始序列号(为什么随机选择,不从0开始?防止使用同一连接标识的两个不同实例,过快地重复使用同一个序号)
③ 允许双方协商一些参数(最大报文段长度、最大窗口大小等)
④ 对传输实体资源进行分配(缓存大小等)
方式:
TCP 连接的建立采用客户-服务器方式
客户主动发起连接建立的应用进程(使用客户端端口号,由协议栈随机生成)
服务器被动等待连接建立的应用进程(使用熟知端口号)
该连接的建立是非对称的(服务器已预先被动打开进入监听状态;连接建立由客户端主动打开开始)
实现——三次握手 Three-way Handshake:
- 最初,两端的TCP进程都处于CLOSED (关闭)状态。服务器进程B被动打开连接,进入LISTEN (收听) 状态,等待客户进程的连接请求
- TCP客户进程A主动打开连接。创建传输控制块TCB,向B发送连接请求报文段,进入SYN-SENT(同步已发送)状态。
- B收到请求后,应答确认报文段,进入SYN-RCVD (同步收到)状态
- A收到B的确认后,向B应答确认,进入ESTABLISHED (已建立连接)状态;B收到A的确认后,也进入ESTABLISHED (已建立连接)状态
PS:为什么A需要向B应答最后一个确认报文段?
为防止“已失效的连接请求报文段”突然又传送到B而产生错误。
PS:“已失效的连接请求报文段”如何产生?
情况一:正常情况(第一次握手确实丢失,导致重新建立连接)
情况二:异常情况(第一次握手延迟到达,导致重新建立连接)
数据传输
最基本的TCP数据传输过程(单向为例):
① 有特定序列号值(SequenceNum)的数据,从发送方向接收方流动:
- 每字节顺序编号
- 每个报文段中的序列号值指的是本报文段所发送的数据的第一个字节的序号
② 对数据的接收确认(Acknowledgment)、接收窗口大小 (AdvertisedWindow),由接收方向发送方应答
基于滑动窗口算法实现可靠的字节流传输
- 何时发送一个报文段 – 触发传输
- 丢包/延时怎么办 – 丢失恢复
- 发送速率不能超过接收方接收能力 – 流量控制
- 尽量避免拥塞并尽可能利用网络带宽 – 拥塞控制
连接释放
① 连接的任何一方都可以主动关闭连接(发送FIN报文段,表示己方不再发送数据)
② 另一端可以继续发送数据(TCP是一个全双工传输协议,双向的字节流传输,两个方向的数据传输可能不会同时结束;单向的数据传输仍需要得到接收方的确认报文段)
③ 异常情况下,任何一方都可以发送RST报文段关闭连接
实现——连接释放:
- A、B都处于ESTABLISED状态,假设A先传输完数据,主动关闭TCP连接。A向B发送连接释放报文段,进入FIN-WAIT-1 (终止等待1)状态
- B收到A的连接释放报文段后,应答确认,进入CLOSE-WAIT (关闭等待)状态。TCP服务器进程此时应通知高层应用进程,从A到B的连接就释放了,TCP连接处于半关闭(half-close) 状态
- A收到B的确认后,进入FIN-WAIT-2 (终止等待2) 状态。B到A方向的连接未关闭,B若发送数据,A仍要接收
- 若B已没有向A的数据,其应用进程通知TCP释放连接。B向A发送连接释放报文段后,进入LAST-ACK (最后确认) 状态
- A收到B的连接释放报文段后,回复确认,进入TIME-WAIT (时间等待) 状态。B收到A的确认后,撤销传输控制块TCB,进入CLOSED状态
- A必须经过时间等待计时器(TIME-WAIT timer) 设置的时间2MSL后,进入CLOSED状态。MSL (Maximum Segment Lifetime, 最长报文段寿命),RFC793设为2分钟,允许设为更小值
PS:为什么A在TIME-WAIT状态必须等待2MSL的时间呢?
两个理由:
① 确保A发送的最后一个ACK报文段能够到达B
② 防止“已失效的连接报文段”出现在本连接中
TCP 滑动窗口
滑动窗口是TCP的核心算法
功能:
- 保证数据的可靠传递
- 确保数据的有序传递
- 增强发送方对接收方的流量控制
接收方根据分配给该TCP连接的缓存数量,动态选择适合的“接收窗口”大小,并通知发送方,使其调整其发送窗口大小,从而改变发送方的发送速率 - 网络拥塞控制
通过改变发送窗口大小控制发送速率,使得发送速率适应网络处理能力的变化
可靠和有序传输:
接收方的TCP——维护一个接收缓冲区
TCP 流量控制
目的:
防止快发送方给慢接收方发数据造成接收崩溃,缓冲区溢出
原理:
- 接收方:根据缓存大小确定接收窗口AdvertisedWindow大小,并通知发送方
- 发送方:① 发送窗口上限值(MaxWindow) ≤ AdvertisedWindow;② MaxWindow = MIN (CongestionWindow, AdvertisedWindow)
要求:
接收方确定AdvertisedWindow大小
- 必须保持:LastByteRecvd – LastByteRead ≤ MaxRcvBuffer
- AdvertisedWindow = MaxRcvBuffer – ( (NextByteExpected – 1) - LastByteRead)
代表缓冲区中剩余的空间数量
新的数据到达,NextByteExpected 指针右移,窗口大小可能变小
窗口是否缩小依赖于应用进程读取数据的速度与数据到达的速度的相对快慢
发送方根据AdvertisedWindow值确定有效窗口,限制发送速率。有效窗口大于0,才能发送更多数据 - 有效窗口(EffectiveWindow) = AdvertisedWindow – (LastByteSent - LastByteAcked)
- 发送方还必须同时保证发送缓存区不溢出 LastByteWritten – LastByteAcked ≤ MaxSendBuffer
PS:慢接收进程如何对快发送进程进行流控?
接收方 B
- 接收进程读取数据的速率小于数据到达速率,每个报文段的到达,都使得AdvertisedWindow变小,直到0
发送方 A - 得知AdvertisedWindow为0,不再发送任何数据,即使它之前发送的数据被成功确认
- 发送缓冲区,会因为发送应用进程写入数据,逐渐被填满
- TCP将阻塞发送应用进程
直到,接收方 B - 接收应用进程重新开始读取数据,TCP打开通知窗口,即AdvertisedWindow不再为0
发送方 A - 发送方TCP把数据从它的缓冲区发送出去
- 当这个数据被确认,释放出相应缓存空间
- 发送进程结束阻塞,被允许继续执行
PS:某些情况下,发送方 A 无法知道AdvertisedWindow已不再为0?
答:当B没有数据需要向A发送时
原因:TCP仅在它有数据或者有确认需要向对端发送时才会发送报文段
- 当AdvertisedWindow为0后,A不能再向B发送数据,因此B不会向A发送确认报文段
- 同时,B没有数据需要向A发送,因此也不会向A发送数据报文段
- 因此,即使B的接收缓冲有了空间, AdvertisedWindow不再为0了,也没有机会通告A,因为没有机会触发报文段的发送
- A 和 B 陷入了相互等待的死锁局面
解决方案:发送方主动定期探测。TCP为每个TCP连接设置一个持续计时器,只要TCP连接的一方收到对方的0窗口通知,就启动该计时器。计时器到期,发送零窗口探测报文 (仅携带1字节数据),对方将确认这个探测报文,同时给出了现在的窗口值,若收到的确认报文中AdvertisedWindow仍为0,重新设置该定时器;直到收到对方的确认报文中AdvertisedWindow不为0。
PS:接收窗口的大小受哪些因素影响?
应该为多少——与时延带宽积相匹配
可以为多少——受缓存空间限制
TCP 触发传输
PS:TCP如何决定传输一个报文段?
TCP支持字节流抽象
应用程序把字节写到流里 (连接对应的发送缓存)
由TCP决定何时从缓存中取出多少字节组成报文段发送
三种触发机制
- TCP 维持一个变量,最大报文段长度 MSS,只要缓存区中存放的数据达到 MSS 字节时,就组装成一个 TCP 报文段发送出去(空间驱动)
通常把MSS设置为TCP能发送而且不造成本地IP分段的最大报文长度 - 发送进程明确要求TCP发送一个报文段,即 TCP 支持的推送 (push)操作(业务驱动)
应用进程调用push操作,使TCP将发送缓存区中所有未发送字节发送出去 - 发送方的一个计时器到期,就把当前缓存区中所有数据装入报文段发送出去(时间驱动)
Nagle算法
- 若窗口允许,发送满载报文段;否则:
- 若当前没有传输中的报文段,也可以立即发送一个小报文段
- 但如果有传输的报文段,发送方必须等到ACK到达才能发送下一个报文段
在任意时刻,TCP连接中只有一个未被确认的小分组在传送,既使得小分组不至于一直等待下去得不到传输机会,又不至于使网络中存在大量的小分组浪费网络资源,是效率与公平性之间的一种平衡策略
TCP 丢失恢复
丢包检测和重传机制是实现 TCP可靠传输的关键
- TCP 每发送一个报文段,就对这个报文段设置一个定时器。超时重传时间 RTO (Retransmission Time-Out)
- 定时器到期,还没有收到确认,就重传该报文段
超时重传时间很难给定,很难给出任意TCP连接两端之间RTT的可能范围
- TCP 的下层是互联网环境,IP 数据报所选择的路由变化很大
- 同一结点的不同TCP连接的RTT可能差异很大
- 同一TCP连接在不同时间,甚至几分钟内,RTT值也有变化
设置过长,恢复丢包效率低;设置过短,导致误重传 (Spurious Retransmission)
自适应重传
原始算法存在缺陷:
① ACK是对接收数据(序号)进行确认,而不是对报文段进行确认
- 当报文段被重传过,无法确定接收到的ACK是针对原始报文段还是重传报文段回复的,因此无法正确计算 ????????????????????????????????????。错把针对重传报文段的ACK当成针对第一个报文段的,????????????????????????????????????过大;相反, ????????????????????????????????????过小。
Karn/Partridge算法
超时值????????????的计算需要准确
- 基本原因:关系重传效率
- 关系网络拥塞问题
超时太快,可能导致不必要的重传,增加网络负载
超时被用于隐式地指示 (暗示) 发生了拥塞,会触发拥塞控制机制
原始算法对????????????的计算过于简单,未考虑到RTT样本值的变化情况
- 若 ???????????????????????????????????? 变化较小,则 ???????????????????????????????????????????????? 的值更可信, 没必要把这个值乘以2来计算 ????????????
- 若 ???????????????????????????????????? 变化大,说明 ???????????? 应远不止 ???????????????????????????????????????????????? 的 2 倍
旧的EstimatedRTT仍然影响计算,但实际RTT与SampleRTT更接近
Jacobson/Karels算法
超时重传的效率问题
超时重传,作为TCP中最基本的重传机制,通常效率很低
超时的粗粒度实现方法导致连接在等待一个定时器超时时,很长一段时间连接无效
快速重传 fast retransmit
快速重传通常可以在1个RTT内重传数据丢包,因为数据包通常都是连续发送的
网络的吞吐量提高约20%
快速重传不能代替常规超时机制,仅是增强功能。并非取消超时重传定时器,而是在某些情况下可更早地触发重传丢失的报文段
时间戳 TimeStamp 选项
更细粒度地测量RTT
发送方在发送报文段时,写入发送时刻的时钟值,并能从接收到的ACK读取该值
发送方接收到ACK后,用当前时钟值减去这个值,即可测出RTT
不需要两端时钟同步,因为读写都是同一端在操作
TCP 拥塞控制
Q:网络如何传输分组,实现数据在主机与主机之间的传输
IP以及下层技术
Q:如何实现应用进程间端到端的可靠传输
TCP
Q:端系统应该以什么样的速率发送数据?
接收方能够承受:流量控制(Flow Control):防止发送方发出的数据超出接收方的接收能力
网络能够承受:拥塞控制(Congestion Control) :防止过多数据注入网络造成网络结点或链路超载
网络拥塞的原因:
从吞吐量角度看还是挺理想的状态
从时延角度不是理想状态
在这种极端理想化的情况中,仍能发现网络拥塞的一种代价:分组到达速率接近链路容量时,分组将经历巨大的排队时延
网络拥塞的另一种代价:发送方必须执行重传以补偿因为缓存溢出而丢弃的分组;发送方在遇到大时延时,可能进行不必要重传,从而引起路由器及其链路资源的浪费。
网络拥塞的另一种代价:当一个分组沿一条路径传输过程中被丢弃时,每个上游路由器用于转发该分组而使用的传输容器最终被浪费掉了
多个传输流共享(争用)网络内资源,资源需求超过网络容量时,产生问题
- 每条流不知道当前网络资源分配情况
- 每条流也不知道其它(竞争)流的存在
后果
丢包率升高、时延增大、甚至网络崩溃 (Network Collapse)
挑战:如何协调网络内各条流,使其可以高效利用网络资源?
- 发送速率适应网络瓶颈
- 发送速率适应网络处理能力的变化
- 多条流公平地共享资源
TCP(端到端)的拥塞控制
TCP可以通过改变发送窗口大小控制发送速率。TCP连接利用发送窗口控制可同时发送 (未确认) 的数据量
窗口大小
- MaxWindow = min (cwnd, AdvertisedWindow)
- 通知窗口 (AdvertisedWindow):接收方决定,可以同时发出的最大字节数以防止超出接收方的接收能力
- 拥塞窗口cwnd (Congestion Windows):拥塞控制算法决定,可以同时发出的最大字节数以防止造成网络拥塞
拥塞检测
丢包是网络拥塞的主要迹象,可以通过丢包进行隐式的拥塞反馈
通过ACK判断丢包
TCP判断拥塞的两个依据:
- 报文段超时
现在通信线路的传输质量一般都很好,因传输出差错而丢弃分组的概率是很小的(远小于 1 %),出现超时,就可以猜想网络可能出现了拥塞 - 收到多个重复ACK
收到一个重复ACK,就知道接收方必定收到乱序到达的报文段,表明其前面的分组可能丢失
发送速率 (拥塞窗口大小)调整
慢启动 slow-start
基本思想
- 主机开始发送数据 (连接刚建立) 或当判断拥塞发生时,不确定网络状况,应避免注入大量数据而引起拥塞
- 拥塞窗口大小从很小的初始值开始,发送成功则快速增大,以探测网络的负载能力
拥塞窗口cwnd的初始值
- 旧的规定:初始拥塞窗口cwnd 设置为 1 至 2 个发送方的最大报文段 MSS (Maximum Segment Size) 的字节数
- 新的 RFC 5681: 把初始拥塞窗口 cwnd 设置为不超过2至4个MSS
拥塞窗口cwnd的增长
- 在每收到一个对新的报文段的确认后,把cwnd增加1个 MSS 的数值数
慢启动也存在问题:拥塞窗口快速增长到一定值会导致大量丢包
当大致估计到网络负载能力时,应采用一种更缓和的调整机制
拥塞窗口的增减策略
TCP拥塞避免
TCP拥塞控制算法
慢启动 (slow start)
拥塞避免 (AIMD)
快重传 (fast retransmit)
快恢复 (fast recovery)
网络中间设备对TCP性能的影响
主动队列管理
随机早期检测 RED
最后
以上就是兴奋大侠为你收集整理的计算机网络:传输层传输层的全部内容,希望文章能够帮你解决计算机网络:传输层传输层所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复