计网-谢希仁-第五章 运输层 读书笔记

重要概念 :

  1. 运输层为相互通信的应用进程提供逻辑通信.
  2. 端口和套接字的意义.
  3. 无连接的 UDP 的特点.
  4. 面向连接的 TCP 的特点.
  5. 在不可靠的网络上实现可靠传输的工作原理, 停止等待协议和 ARQ 协议.
  6. TCP 滑动窗口, 流量控制, 拥塞控制, 连接管理.

5.1 运输层概述

5.1.1 进程之间的通信

运输层向它上面的应用层提供通信服务, 它属于面向通信的最高层, 同时也是用户功能中的最底层.

从 IP 层来看, 通信的两端是两台主机. 但实际上, 真正的实体是进程, 是这两台主机的一个进程与另一台主机的一个进程交换数据.

端到端的通信是进程的通信.

通常, 一台主机中经常有多个应用进程同时分别和另一台主机中多个应用进程通信, 这体现了运输层的重要功能 : 复用分用.

复用 : 指在发送方不同的应用进程都可以使用同一个运输层协议传送数据.

分用 : 指接收方的运输层在剥去报文的首部后能够把这些数据正确交付目的应用进程.

img

网络层为主机之间提供逻辑通信, 而运输层为应用进程之间提供端到端的逻辑通信.

两种协议 : 面向连接的 TCP无连接的 UDP.

采用 TCP 协议时 : 尽管下面的网络不可靠 (只提供尽最大努力交付), 但这种逻辑通信信道相当于全双工信道.

采用 UDP 协议时 : 仍是不可靠信道.

5.1.2 两大协议

img

UDP 在传送数据前不需要建立连接. 远地主机的运输层收到 UDP 报文后, 不需要给出确认.

TCP 则提供面向连接的服务. 在传送数据之间必须先建立连接, 数据传送结束后要释放连接. 不提供广播和多播.

如图是一些应用和应用层协议主要使用的运输层协议 :

img

5.1.3 运输层的端口

虽然通信的终点是应用进程, 但只要把所传送的报文交到目的主机的某个合适的端口, 剩下的工作就由 TCP 或 UDP 完成.

协议栈层间的抽象的协议端口是软件端口, 软件端口是应用层的各种协议进程与运输实体进行层间交互的一种地址.

端口号只有本地意义, 不同计算机的端口没有关联.

客户在发起通信请求时, 必须知道对方服务器的 IP 地址 和端口号. 端口号分为两大类 :

  1. 服务器使用的端口号 这里又分两类, 一是熟知端口号, 数值 0 ~ 1023. 另一种是登记端口号, 数值为 1024 ~ 49151. 为没有熟知端口号的应用程序使用.
  2. 客户使用的端口号 数值为 49152 ~ 65535. 这类端口仅在客户进程运行时动态选择. 当服务器进程收到客户进程的报文时, 就知道了客户进程使用的端口号, 因而可以把数据发送给客户进程.
img

5.2 用户数据报 UDP 协议

5.1 .1UDP 概述

UDP 只在 IP 数据报上加了一点功能, 即复用和分用以及差错检测. 主要特点 :

  1. 无连接.
  2. 尽最大努力交付.
  3. 面向报文 : UDP 一次交付一个完整的报文, 既不合并, 也不拆分.
  4. 没有拥塞控制.
  5. 支持一对一, 一对多, 多对多.
  6. 首部开销小. 只有 8 字节, TCP 有 20 字节.

5.2.2 UDP 首部格式

有两个字段 : 数据字段首部字段. 8 个字节, 4 个字段.

  1. 源端口.
  2. 目的端口.
  3. 长度 最小为 8 (只有首部).
  4. 检验和 : 检测是否有错, 出错丢弃.
img

当运输层从 IP 层收到 UDP 数据报时, 就根据首部的目的端口, 把 UDP 数据报通过相应的端口, 上交到应用进程.

img

如果接收方 UDP 发现报文目的端口号不对, 就丢弃该报文, 并由 ICMP 发生 "端口不可达" 差错报文给发送方.

UDP 的通信是无连接的, 因此不使用套接字.

5.3 传输控制协议 TCP

5.3.1 TCP 的特点

  1. TCP 面向连接 : 应用程序在使用 TCP 协议前, 必须先建立 TCP 连接. 在传送数据完毕后, 必须释放连接.
  2. 点对点.
  3. 可靠交付.
  4. 全双工 : TCP 允许通信双方的应用进程任何时候都能发送数据. TCP 连接的两端都设有发送缓存和接受缓存.
  5. 面向字节流 : 是指流入到进程或从进程流出的字节序列. "面向字节流" 的含义 : 虽然应用进程和 TCP 的交互是一次一个数据块, 但 TCP 把应用进程交下来的数据仅仅看成一连串无结构字节流, TCP 不知道字节流的含义.
img

TCP 的连接是虚连接 (逻辑连接).

TCP 和 UDP 在发送报文时所采用的 方式完全不同 : TCP 不关心应用进程一次把多长的报文发送到 TCP 缓存, 而是根据对方给出的窗口值当前网络的拥塞程度来决定一个报文段有多少个字节. 而UDP发送的报文长度是应用进程给出的.

5.3.2 TCP 的连接

TCP 连接的端点叫 套接字(socket).

\[套接字 socket=(IP地址:端口号) \]

每一条 TCP 连接唯一地被通信两段的两个端点 (即两个套接字) 所确定 :

\[TCP连接::=\{socket_1,socket_2\}=\{(IP_1:prot_1),(IP_2:port_2)\} \]

5.4 可靠传输的工作原理

理想传输 :

  1. 传输信道不产生差错.
  2. 不管发送方以多快速度发送数据, 接受方总是来得及处理收到的数据.

5.4.1 停止等待协议

1. 无差错情况

流程如图(a) : M 是分组.

img

2. 出现差错

如图(b) : B 接受 \(M_1\) 是检测出错, 就丢弃 \(M_1\), 其他什么都不做.

超时重传 : A 只要超过一段时间仍然没有收到确认, 就认为分组丢失, 因此需要重传. 为了实现重传, 需要设置一个超时计时器, 在超时计时器到期前收到确认, 就撤销该计时器.

注意三点 :

  1. A 发送一个分组后, 必须保留其副本.
  2. 分组和确认分组必须编号, 这样才明确是哪一个收到了确认, 哪一个没有.
  3. 超时计时器设置的重传时应当比数据在分组传输的平均往返时间更长一些.

3. 确定丢失和确认迟到

img

如图(a) : B 所发送的对 \(M_1\) 的确认丢失了. A 在设定的超时重传时间内没收到确认, A 不知道是自已的分组出错, 丢失, 还是 B 的确认丢失. 因此 A 在超时计时器到期后就要重传 \(M_1\). 假定 B 又收到了这个重复的分组 \(M_1\) :

  1. 丢弃这个重复的分组.
  2. 向 A 发送确认.

图(b)是另一情况 : 传输无差错, 但是 B 对 \(M_1\) 的确认迟到了, A 会收到重复的确认. 这时 : A 收下后就丢弃, B 也会收到重复的 \(M_1\), 同样丢弃, 并重传确认分组.

像上述可靠传输协议称为 : 自动重传请求 ARQ. 指重传的请求是自动的.

通过确认和重传机制, 就可以在不可靠的传输网络上实现可靠的通信.

5.4.2 连续 ARQ 协议

如图(a) 表示发送方维护的发送窗口, 它的意义 : 位于窗口内的分组都连续发送出去, 而不需要等待对方确认.

发送方每收到一个确认, 就把发送窗口向前滑动一个分组的位置.

接收方采取累计确认的方式 : 不必对每个分组都发送确认, 而是对按序到达的最后一个分组发送确认.

如果中间的分组丢失, 需要回退.

img

5.5 TCP 报文段的首部格式

TCP 面向字节流, 传输单元还是报文段, 一个 TCP 报文段分为首部和数据两部分.

TCP 报文首部 20 字节是固定的, 后面有 4n 字节是根据需要的选项.

img

首部各字段 :

  1. 源端口和目的端口. 各 2 字节.
  2. 序号 seq. 4 字节, 范围 \([0,2^{32}-1]\), 序号采用 \(mod\ 2^{32}\) 运算. TCP 连接传送的字节流中的每一个字节按顺序编号. 起始字节序号必须在连接建立时设置.
  3. 确认号 ack 4 字节, 是期望收到对方下一报文段的第一个数据字节的序号. 若确认号 = N, 表明序号 N - 1 为止的所有数据都已正确收到.
  4. 数据偏移 4 字节, 指出 TCP 报文段数据部分距离 TCP 报文段起始有多远, 实际上就是首部长度.
  5. 保留 6 位
  6. 紧急 URG 当 URG = 1 时, 表明此报文有紧急数据.
  7. 确认 ACK 当 ACK = 1 时, 确认号才有效.
  8. 推送 PSH
  9. 复位 RST 当 RST = 1 时, 表示 TCP 连接出错, 必须释放连接.
  10. 同步 SYN 连接时同步序号.
  11. 终止 FIN FIN = 1 时, 表示要求释放连接.
  12. 窗口 2 字节. 范围 \([0,2^{32}]\) . 作为接受方让发送方设置其发送窗口的依据, 指自已的接受窗口.

窗口字段指明了允许对方发送的数据量. 其值是动态变化的.

  1. 检验和 2 字节.
  2. 紧急指针 2 字节. URG = 1 时才有效.
  3. 选项 最长 40 字节. 如 MSS : 数据字段最大长度.

5.6 TCP 可靠传输的实现

5.6.1 以字节为单位的滑动窗口

滑动窗口以字节为单位. 假定 A 收到了 B 发来的确认报文段, 其中窗口 20 字节, 确认号 31, 于是, A 构造除了自已的发送窗口.

img

在没有收到 B 确认情况下, A 可以连续发送窗口内的数据, 但必须保留 (窗口不动), 以便重传.

img

用三个指针描述窗口 : \(P_1\), \(P_2\), \(P_3\).

小于 \(P_1\) : 已发送且收到确认.

大于 \(P_3\) : 不允许发送.

\(P_3-P_1=A\) 的发送窗口.

\(P_2-P_1=\) 已发送但还未收到确认的字节数.

\(P_3-P_2=\) 允许发送但未发送的字节数.

若 B 未收到 31 的数据, 但收到了 32, 33, 那么 32, 33 即未按顺序收到. 此时 B 发送回去的确认报文的 ack = 31​ 而不是 32 或 33.

现在假定 B 收到了 31 号数据, 并把 31 ~ 33 交给了主机. B 就删除它们, 并把窗口前移 3 位. 同时给 A 发送确认, 窗口仍 = 20, 但 ack = 34.

img

B 还收到了 37, 38, 40 的数据, 它们没有按序到达, 于是先放在接受窗口中. A 收到 B 的确认后, 发送窗口向前滑动 3 个序号, 但 \(P_2\) 不动.

A 继续发送 42 ~ 53 后, \(P_2\)\(P_3\) 重合. 还没收到确认, 停止发送. 当发送分组数据都达到 B, B 就返回确认.

img

若 A 在没收到确认 (超时计时器控制) 就重传这部分数据 并重新设置超时计时器, 直到收到 B 的确认.

下图为发送方发送缓存与发送窗口的关系图, 以及接收方接受缓存与接受窗口的关系图 :

img

5.6.2 超时重传时间的选择

5.6.3 选择确认 SACK

5.7 TCP 的流量控制

流量控制 : 让发送方的发送速率不要太快, 要让接收方来得及接受.

5.7.1 利用滑动窗口实现流量控制

img

B 进行了三次流量控制 : 第一次把窗口减小到 rwnd = 300, 第二次 rwnd = 100, 最后 rwnd = 0, 即不允许发送方发送数据.

5.7.2 TCP 的传输效率

控制 TCP 发送的时机 :

  • MSS (最大报文长度)
  • 推送机制
  • 计时器

广泛使用 Nagle 算法

5.8 TCP 拥塞控制

拥塞 : 对网络某一资源的需求超过该资源可提供的可用部分, 网络性能就要变坏.

img

TCP 拥塞控制的方法有四种 :

  1. 慢开始.
  2. 拥塞避免.
  3. 快重传.
  4. 快恢复.

网络层对 TCP 拥塞控制影响最大的是路由器的分组丢弃策略.

为了避免网络中全局同步现象, 引入了主动队列管理 AQM.

5.9 TCP 的运输连接管理

运输连接三阶段 : 连接建立, 数据传送, 连接释放.

5.9.1 TCP 连接建立

TCP 建立连接的过程叫做握手. 握手需要在客户和服务器之间交换三个 TCP 报文段.

img

一开始, B 的 TCP 服务器进程先创建传输控制块 TCB, 进入 LISTEN (收听) 状态, 等待用户的连接.

A 的 TCP 客户进程也是首先创建传输控制块 TCB, 在连接前, 向 B 发出连接请求报文段, 这时首部中的同步 SYN = 1, 同时选择一个初始序号 seq = x. SYN 报文段 (即 SYN = 1) 不能携带数据, 且消耗一个序号, 这时, TCP 客户进程进入 SYN-SENT (同步已发送) 状态.

B 收到连接请求报文段后, 如同意建立连接, 则向 A 发送确认. 在确认报文段中应把 SYN 位和 ACK 位都置 1, 确认号是 ack = x + 1, 同时也为自已i选择一个初始序号 seq = y. 这时 TCP 服务器进程进入 SYN-RCVD (同步收到) 状态.

TCP 客户进程收到 B 的确认后, 还要向 B 给出确认. 确认报文段 ACK 置 1, 确认号 ack = y + 1, 而自已的序号 seq = x + 1. 这时, TCP 连接已经建立, A 进入 ESTABLISHED 状态.

以上过程称为 TCP 三报文握手.

为什么 A 最后一次确认 ?

主要是为了防止已失效的连接请求报文突然又传送到 B, 因而产生错误.

  1. A 发出了连接请求, 但连接请求报文未收到确认, 于是 A 再重传连接请求, 后来收到了确认, 建立了连接.
  2. A 发出了连接请求报文段没有丢失但迟到了, 以致延误到连接释放后才到 B, B 收到后, 误以为 A 又发起了连接请求, 于是向 A 发出确认报文段, 同意连接, 假定没有 A 的最后一次确认, B 就会以为新的连接已建立, 并一直等着 A 的数据, 这样 B 的资源就被浪费了.

5.9.2 TCP 的连接释放

数据传输后, 双方都可以释放连接.

现在 A 和 B 都处于 ESTABLISHED 状态. A 的应用进程先向其 TCP 发出连接释放报文段, 并停止发送数据, 主动关闭 TCP 连接. A 把连接释放报文段的 FIN 置为 1, seq = u, 它等于前面的最后一个字节序号 + 1. A 进入 FIN-WAIT-1 状态, 等待 B 确认. FIN 消耗一个序号.

img

B 收到连接释放报文段后即发出确认, 确认号 ack = u + 1, 自已的序号是 v, 为 B 前面传送过的最后一个字节 + 1. 然后 B 进入 CLOSE-WAIT 状态. TCP 服务器进程这时通知高层应用层, A 到 B 的连接释放, 这时 TCP 连接处于半关闭状态, B 若发数据, A 仍要接受.

A 收到 B 的确认后, 进入 FIN-WAIT-2 状态, 等待 B 发出连接释放报文段.

当 B 没有向 A 发送的数据后, 应用进程就通知 TCP 释放连接. B 发出的连接释放报文段 FIN = 1, 序号 w, ack = u + 1. B 进入 LAST-ACK 状态.

A 收到 B 连接释放报文段后. 在确认报文段中 ACK = 1, seq = u + 1, ack = w + 1. 进入 TIME-WAIT 状态. 注意 : 此时 TCP 还未释放, 必须经过时间等待计时器设定的时间 2MSL后. A 才进入 CLOSED 状态. MSL : 最长报文段寿命.

为什么 A 在 TIME-WAIT 状态需要等待 2MSL 时间 ?

  1. 为了保证 A 发送的最后一个 ACK 报文段能到达 B. 假定这个报文丢失, B 没有收到确认, 就会重新发送 FIN + ACK 报文段, 在 2MSL 时间内 A 能收到 B 的重传, 并重新发送自已的确认给 B. 没有这个时间, B 收不到确认, 就无法进入 CLOSED 状态.
  2. 防止失效的连接请求又出现, 等待了 2MSL 时间, 保证了本连接的所有报文都从网络中消失, 这样就使下一个新的连接不会出现旧的报文段.

上述为 TCP 四报文握手.

posted @ 2021-05-15 09:57  phr2000  阅读(170)  评论(0编辑  收藏  举报