动画有助于更好地理解
interactive animation speaks a thousand words
断更好几天了(趴)
# 第三章 运输层
在网络层的基础上增加了端口号来实现进程到进程的通信。
# 概述
TCP:可靠的、保序的传输,提供多路复用、解复用,拥塞控制、流量控制、建立连接
UDP:不可靠的、不保序的传输,提供多路复用和解复用
都不提供延时保证和带宽保证,延时和带宽依赖于网络层的服务
# 多路复用与多路分解
multiplexing and demultiplexing
在源主机从不同的套接字中收集数据块,并为每个数据块封装上首部信息,从而生成报文段,然后将报文段传递到网络层,所有这些工作称多路复用。
- 每个套接字有唯一标志符
- 传输层 / 运输层报文段中包含源端口号、目的端口号、传输数据等
将运输层报文段中的数据交付到正确的套接字的工作称为多路分解。
以上可用两家小孩寄邮件类比理解。
# 端口号
0-65535
0-1023 周知端口号 / 著名端口号 well-known port number
一般而言,应用程序的客户端让运输层自动地(也是透明地)分配端口号,而服务器端则分配一个特定的端口号。
# 面向无连接的多路复用与多路分解
一个 UDP 套接字是由一个二元组全面标识的,包含一个目标 IP 地址和一个目的端口号。
如果两个 UDP 报文段有不同的源 IP 地址和 / 或源端口号,但具有相同的目的 IP 地址和目的端口号,那么这两个报文段将通过相同的目的套接字被定向到相同的目的进程。
# 面向连接的多路复用与多路分解
一个 TCP 套接字是由一个四元组全面标识的,包含源地址、源端口、目的 IP 地址、目的端口。
不同的源将定向到不同的目的进程。
# Web 服务器与 TCP
连接套接字与进程之间并非总是有着一一对应的关系。如今一些高性能的 Web 服务器通常只有一个进程,但是为每个新的客户连接创建一个具有新连接套接字的新线程。
# 无连接运输:UDP
# UDP 的优点 / 为什么要使用 UDP:
- 关于发送什么数据以及何时发送的应用层控制得更为精细
- 无须连接建立
- 无连接状态
- 分组首部开销小
# UDP 检验和
端到端原则:某种功能必须是基于端到端的实现,“与在较高级别提供这些功能的代价相比,在较低级别设置的功能可能是冗余的或几乎没有价值的、”
回卷、反码
在目标地址,将四个比特字加在一起,每一位为 1,则无差错。
# 可靠数据传输(rdt)的原理
rdt: reliable data transfer protocol
双向的数据传输协议就是两个单向的数据传输协议的综合
FSM Finite-State Machine
# 构造可靠数据传输协议
# 基于完全可靠信道 rdt1.0
直接传就好了 Orz
# 经具有比特差错信道的可靠数据传输 rdt2.0
ARQ Automatic Repeat reQuest 自动重传请求协议
- 差错检测
- 接收方反馈(ACK, NAK)
- 重传
停等(stop-wait)协议:发送方将不会发送一块新数据,除非发送方确信接收方已正确接受当前分组。
# 如果 ACK/NAK 出错 -> rdt2.1
增加序号 0,1
根据收到的序号即可确定是否正在重传前一个发送分组
# NAK free 在 ACK 后加序号 -> rdt2.2
为后面发送多个数据做准备
确认信息减少一般,协议简单
# 经具有比特差错的丢包信道的可靠数据传输 rdt3.0
比特交替协议 alternating-bit protocol
设置倒计数计时器 (countdown timer) ,一旦超过时间,则重传
虽然可能造成冗余数据分组(duplicate data packet),但 rdt2.0 已经处理了这部分内容
# 流水线可靠数据传输协议
rdt3.0 的停等协议降低了传输的性能,等待到收到回复后才进行下一步操作,链路的利用率太低。
因此,开发了流水线技术,即一次传输多个分组。
# 回退 N 步 Go-Back-N —— 如何处理流水线的差错恢复
N - window size 窗口长度
sliding-window protocol 滑动窗口协议
# 发送方响应的事件
上层调用
收到一个 ACK 累计确认
超时事件
如果出现超时,发送方重传所有已发送但还未被确认过的分组。
如果收到一个 ACK,但仍有已发送但未被确认的分组,则定时器被重新启动。
# 接收方
接收方若收到 失序、错误分组,则丢弃该分组,并为最近按序接收的分组重新发送 ACK。
# 优点
接收缓存简单
# 缺点
单个分组的差错就能引起 GBN 重传大量分组
(配套的 GBN Java 小程序好好玩
# Selective Repeat SR —— 如何处理流水线的差错恢复
# 接收方
失序的分组将被缓存直到所有丢失分组(即序号更小的分组)皆被接收
接收到后为接收的分组发送 ACK
不在缓存范围内的分组将被丢失
# 发送方
从上层收到数据
超时 —— 每个分组都要有自己的逻辑计时器,超时发送后只能发送一个分组。
收到 ACK—— 窗口基序号向前移动到具有最小序号的未确认分组处,如果窗口移动了并且有序号落在窗口内的为发送分组,则发送这些分组。
具体可实际操作一下小程序
出错率低适合用 GBN,链路容量大适合用 SR
# 面向连接的运输:TCP
# TCP 连接
全双工服务 full-duplex service
最大报文段长度 MSS Maximum Segment Size
# TCP 报文段结构
Holy &^%@! That idiot made a TCP header diagram in Lego(TM)!
有趣,但孩子不玩乐高(x
https://righteousit.wordpress.com/2010/06/27/practical-visual-three-dimensional-pedagogy-for-internet-protocol-packet-header-control-fields/
源端口号、目标端口、序号、确认号、首部长度、保留未用、标志字段、接收窗口、因特网检验和、紧急数据指针、选项、数据
# 序号和确认号
在主机 A 的一个进程与主机 B 的一个进程的连接中,主机 A 填充进报文段的确认号是主机 A 期望从主机 B 收到的下一字节的序号。
累积确认:TCP 只确认该流中至第一个丢失字节为止的字节
捎带:对客户到服务器的数据的确认被装载在一个承载服务器到客户的数据的报文段中
# 往返时间的估计与超时
指数加权移动平均:根据较近的 SampleRTT 的值估计目前的平均
超时间隔
(用了一些公式计算出了 EstimatedRTT 和 DevRTT,进而估算 TimeoutInterval)
# 可靠数据传输
超时间隔加倍:再次超时,超时间隔设置为原来的两倍
冗余 ACK:一旦收到 3 个冗余 ACK,TCP 就执行快速重传(fast retransmit)
TCP 是 GBN 和 SR 协议的混合体
# 流量控制
区分流量控制和拥塞控制。
流量控制是端到端的控制,例如 A 通过网络给 B 发数据,A 发送的太快导致 B 没法接收 (B 缓冲窗口过小或者处理过慢),这时候的控制就是流量控制,原理是通过滑动窗口的大小改变来实现。 其中,rwnd 指接收窗口 receive window。
拥塞控制是 A 与 B 之间的网络发生堵塞导致传输过慢或者丢包,来不及传输。防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不至于过载。拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络性能有关的所有因素。
# TCP 连接管理
SYN
FIN
通过三次握手建立连接,两次握手会造成半连接(只有一端维护了连接)
# 拥塞控制原理
拥塞表现:分组丢失、延时较长
# 拥塞原因与代价
- 当分组的到达速率接近链路容量时,分组经历巨大的排队时延
- 发送方必须执行重传以补偿因为缓存溢出而丢失(丢弃)的分组
- 发送方在遇到大时延时所进行的不必要重传会引起路由器利用其链路带宽转发不必要的分组副本
- 当一个分组沿一条路径被丢弃时,每个上游路由器用于转发该分组到丢弃该分组而使用的传输容量最终被浪费调了
# 拥塞控制方法
- 端到端拥塞控制
- 网络辅助拥塞控制(NI 字段表示轻微拥塞,CI 字段表示拥塞指示)
# TCP 拥塞控制
TCP 使用端到端的拥塞控制,而不是网络辅助的拥塞控制。网络辅助的拥塞控制代价过高。
# 指导性原则
- 一个丢失的报文段意味着拥塞,因此当丢失报文段时应当降低 TCP 发送方的速率。
- 一个确认报文段指示该网络正在向接收方交付发送方的报文段,因此,当对先前未确认报文段的确认到达时,能够增加发送方的速率。
- 宽带检测
# TCP 拥塞控制算法
# 慢启动
指数增长,每过一个 RTT,发送速率就翻番
# 拥塞避免
线性增长,无论何时到达一个新的确认,就将 cwnd 增加一个 MSS 字节