计算机网络学习笔记(五)-- 运输层

计算机网络学习笔记(一)-- 计算机网络概述
计算机网络学习笔记(二)-- 物理层
计算机网络学习笔记(三)-- 数据链路层
计算机网络学习笔记(四)-- 网络层

1. 运输层协议概述

  1. 进程之间的通信

    • 向它上面的应用层提供通信服务。
    • 面向通信部分的最高层。
    • 用户功能中的最低层。

    通信的真正端点井不是主机而是主机中的进程。

    tgtV54.png
  2. 运输层的两个主要协议

    • 用户数据报协议 UDP (User Datagram Protocol)

    • 传输控制协议 TCP (Transmission Control Protocol)

    tgN9Fe.png
  3. 运输层的端口

    • 识别各应用层进程;

    • 只具有本地意义;

    端口范围:(0 - 65535)

    ①熟知端口号(0~1023)

    ②登记(或注册)端口号(1024~49151)

    ③客户(或动态、短暂)端口号(49152~65535)

  4. 套接字socket

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

2. 用户数据报协议 UDP

  • 特点

    ① 无连接;(减少开销和发送时延)

    ③ 尽最大努力交付;

    ④ 面向报文;(对报文不分拆,不合并)

    ⑤ 没有拥塞控制;

    ⑥ 支持一对一,一对多,多对一,多对多的交互通信;

    ⑦ 首部开销小。(8个字节)

    ⑧无编号;

  • UDP首部格式

    有 8 个字节 ,由 4 个字段组成,每个字段的长度都是 2 个字节。

    tgNLtg.png

    (1) 源端口:源端口号。在需要对方回信时选用。不需要时可用全 0。

    (2) 目的端口:目的端口号。这在终点交付报文时必须使用。

    (3) 长度:UDP用户数据报的长度,其最小值是 8 (仅有首部)。

    (4) 检验和:检测 UDP 用户数据报在传输中是否有错。有错就丢弃。

    tgUE9J.png

    如果接收方 UDP 发现收到的报文中的目的端口号不正确,就丢弃该报文,并由网 ICMP 发送“端口不可达”差错报文给发送方。

    UDP 的通信是无连接的,虽然使用了端口号但不需要使用套接字。

  • UDP 计算检验和

    把首部和数据部分一起都检验,IP数据报是只检验首部

    tgUhUU.png

    16 位的字视为 1 字节。若数据部分不是偶数个字节,则要填入一个全零字节(但此字节不发送)。

3. 传输控制协议 TCP 概述

  • 特点

    ① 面向连接的服务;

    ② 面向字节流;(无结构的字节流)

    ③ 全双工通信;(发送、接收缓存)

    ④ 复用和分用;(发送—复用,接收—分用)

    ⑤ 进程到进程的通信;(点对点,每个进程都需要一个连接)

    ⑥ 可靠的服务。(无差错,不丢失,不重复,按序到达)

  • TCP 连接

    TCP 之间的通信必须要在两个套接字之间建立连接。

    TCP 连接::= {socket, socket2} = { (IP1: port,), (IP2: port2) }

4. 可靠传输的工作原理

  1. 停止等待协议

    1. 无差错情况和出现差错

      tga0qx.png

      A 向 B 发送,B 收到后向 A 发送确认报文,A 发送下一条报文。若超过一段时间 A 没有收到确认报文就重传该报文。

      A 在发送完一个分组后,必须暂时保留已发送的分组的副本,收到确认后才能销毁。

      分组和确认分组都必须进行编号。

      超时计时器设置的重传时间应当比数据在分组传输的平均往返时间更长一些。

    2. 确认丢失和确认迟到

      tgdZex.png
    3. 信道利用率

      tgdMfe.png
      tgd1ld.png

      当使用流水线传输时,就要使用连续 ARQ 协议滑动窗口协议

  2. 连续 ARQ 协议

    发送窗口,累积确认(对按序到达的最后一个分组发送确认)。

    tg0jOA.png

    对按序到达的最后一个分组发送确认,这就表示:到这个分组为止的所有分组都已正确收到了。

    优点:简单易实现;缺点:Go-back-N,即首尾收到,中间报文段丢失,则要重传丢失报文后的所有报文。

5. TCP 报文段的首部格式

tgBmT0.png

​ 最小长度是 20 字节,后面有 4n 字节是根据需要而增加的选项 (n 是整数),最大长度 60 字节。

  • 源端口和目的端口:各占 2 个字节,分别写入源端口号和目的端口号。

  • 序号:4 字节,使用 mod 2^32 运算。

  • 确认号:4 字节,是期望收到对方下一个报文段的第一个数据字节的序号。

    若确认号= N, 则表明:到序号 N-1 为止的所有数据都已正确收到。

  • 数据偏移:占 4 位,即首部长度。

  • 保留:占 6 位,保留为今后使用,目前置为 0。

  • 紧急 URG:URG = 1 时,表明紧急指针字段有效,相当于优先级高的数据,要尽快传送。

  • 确认 ACK:仅当 ACK = 1 时确认号字段才有效。当 ACK = 0 时,确认号无效。在TCP连接建立后所有传送的报文段都必须把 ACK 置 1。

  • 推送 PSH:PSH = 1 时,立即收到响应,不必等缓存满了之后再向上交付。

  • 复位 RST:RST = 1 时,表明 TCP 连接中出现严重差错,必须释放连接,然后再重新建立运输连接。还用来拒绝一个非法的报文段或拒绝打开一个连接。

  • 同步 SYN:在连接建立时用来同步序号,连接请求和连接接受。当 SYN = 1 ACK = 0 时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使 SYN = 1 ACK = 1 。

  • 终止 FIN:用来释放一个连接。当 FIN = 1 时,表明此报文段的发送方的数据已发送完毕,并要求释放运输连接。

  • 窗口:2 字节,指的是发送本报文段的一方的接收窗口(而不是自己的发送窗口),窗口值作为接收方让发送方设置其发送窗口的依据。

    窗口字段明确指出了现在允许对方发送的数据量。窗口值经常在动态变化着。

  • 检验和:2 字节。检验和字段检验的范围包括首部和数据这两部分,与UDP检验方法相同。

  • 紧急指针:2 字节。紧急指针仅在 URG = 1 时才有意义,它指向最后一字节的紧急数据。即使窗口为零时也可发送紧急数据。

  • 选项:长度可变,最长可达 40 字节。

    1. 最大报文段长度 MSS 选项: TCP数据报数据部分长度。
    2. 时间戳选项:10 字节,其中最主要的字段是时间戳值字段 (4 字节)和时间戳回送回答字段 (4 字节): 用来计算往返时间 RTT,用于处理 TCP 序号超过 2^32 的情况。

6. TCP 可靠传输的实现

  1. 以字节为单位的滑动窗口

    tgsukt.png

    小于 P1 的是已发送并已收到确认的部分,而大于 P3 的是不允许发送的部分。

    P3 - P1 = A 的发送窗口

    P2 - P1 =已发送但尚未收到确认的字节数

    P3 - P2 = 允许发送但当前尚未发送的字节数(又称为可用窗口或有效窗口)

    B 未按序收到,A 从31号重传,B收到后把接收窗口向前移动 3 个序号。A 在继续发送完序号 42 ~ 53 的数据后,指针 P2 向前移动和 P3 重合。

    tgsv38.png
  2. 超时重传时间的选择

    每当第一次测量到 RTT 样本时, RTTs 值就取为所测量到的 RTT 样本 值。但以后每测量到一个新的 RTT 样本,就按下式重新计算一次 RTTs

    新的 RTTs = (1 - α) x (旧的 RTTs) + α x (新的 RTT 样本)

    RTO (超时重传时间) = RTTs + 4 x RTTD (RTT 的偏差的加权平均值)

    新的 RTT0 = (1- β) x (旧的 RTTD)+ β x | RTTs-新的 RTT 样本 |

  3. 选择确认 SACK

    首部选项加上允许 SACK 选项。

    tg66F1.png

7. TCP 的流量控制

流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。

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

    tg6bfP.png

    发送方的发送窗口不能超过接收方给出的接受窗口的数值;

    设置持续计时器来防止窗口由零变为非零导致的僵局。

  2. 传输的效率(三种机制)

    ① 维持一个等于MSS的变量来控制缓存。

    ② 发送方的推送push操作。

    ③ 计时器期限到了就将缓存数据装入报文段。

8. TCP 的拥塞控制

​ 拥塞控制是全局的控制,以网络能够承受现有的网络负荷为前提;流量控制是端口的控制。

  1. TCP 的拥塞控制方法

    • 慢开始和拥塞避免

      发送方让自己的发送窗口等于拥塞窗口。

      判断网络拥塞的依据就是出现了超时。

      慢开始:以 MSS 作为发送窗口大小的初始值(拥塞窗口),每经过一个传输轮次(从发送到确认),cwnd就加倍;慢开始门限作为慢开始和拥塞避免的转换点;

      拥塞避免:每一个RTT,cwnd只加 1, (线性增长,加法增大);

      出现拥塞时,慢开始门限设置为当前窗口值的一半(乘法减小),cwnd设为1;

      tg2pR0.png
      tg2nRx.png
    • 快重传和快恢复

      快重传:收到三个重复确认立即发送未被确认的报文段;

      快恢复:乘法减小后执行加法增大;

      tgRxg0.png
  2. TCP 拥塞控制流程图

    tgWCbF.png

9. TCP 的运输连接管理

运输连接有三个阶段,即:连接建立、数据传送和连接释放。

TCP 连接的建立采用客户服务器方式。

  1. TCP 的连接建立

    tgWwVg.png
    • 第一次握手

      客户端向服务端发送连接请求报文段。该报文段的头部中 SYN = 1,ACK = 0,seq = x。请求发送后,客户端便进入***SYN-SENT*** 状态。

      • SYN = 1,ACK = 0 表示该报文段为连接请求报文。

      • x 为本次TCP通信的字节流的初始序号。TCP规定:SYN = 1 的报文段不能有数据部分,但要消耗掉一个序号。

    • 第二次握手

      服务端收到连接请求报文段后,如果同意连接,则会发送一个应答:SYN = 1,ACK = 1,seq=y,ack=x+1。该应答发送完成后便进入***SYN-RCVD*** 状态。

      • SYN = 1,ACK = 1 表示该报文段为连接同意的应答报文。
      • seq = y 表示服务端作为发送者时,发送字节流的初始序号。
      • ack = x + 1 表示服务端希望下一个数据报发送序号从x+1开始的字节。
    • 第三次握手

      当客户端收到连接同意的应答后,还要向服务端发送一个确认报文段,表示:服务端发来的连接同意应答已经成功收到。该报文段的头部为:ACK=1,seq=x+1,ack=y+1

      • 客户端发完这个报文段后便进入ESTABLISHED状态,服务端收到这个应答后也进入ESTABLISHED状态,此时连接的建立完成!

为什么连接建立需要三次握手,而不是两次握手?

背景:A首先发送一个连接请求,但是该请求在网络节点上滞留了,没有收到确认。于是A重传了一次请求,并且收到了B的确认,于是连接建立,数据传输完成后,释放连接。

① 假定A发出的第一个请求报文段并没有丢失,而是在某些网络节点上滞留,本来是一个失效的请求,但B收到后误认为是A再次发出一个新请求,于是向A发送确认,同意建立连接。

② 假定采用两次握手,那么只要B发出确认,则新的连接就建立了。由于A并没有发出请求,因此不理会B的确认,也不会向B发送数据,但B却以为新的连接已经建立,并一直等待A的数据,B的许多资源就这样白白浪费了。

③ 假定采用三次握手,则B发出确认,但A因为并没有发请求,所以不理会B的确认,B没有收到A的确认,则连接建立失败,B知道连接建立失败。会回收资源。

④ 极端的情况可能由于Client用户端多次重新发送请求数据而导致Server端最后建立了N多个响应在等待,因而造成极大的资源浪费!所以,“三次握手”很有必要。

  1. TCP 的连接释放

    tg5isx.png
    • 第一次挥手
      若A认为数据发送完成,则它需要向B发送连接释放请求。该请求只有报文头,头中携带的主要参数为:FIN = 1,seq = u。此时,A将进入FIN-WAIT-1状态。

      • FIN = 1 表示该报文段是一个连接释放请求。
      • seq = u,u - 1 是A向B发送的最后一个字节的序号。
    • 第二次挥手
      B收到连接释放请求后,会通知相应的应用程序,告诉它A向B这个方向的连接已经释放。此时B进入 CLOSE-WAIT 状态,并向A发送连接释放的应答,其报文头包含:ACK = 1,seq = v,ack = u + 1。A收到该应答,进入 FIN-WAIT-2 状态,等待B发送连接释放请求。

      • ACK = 1:除TCP连接请求报文段以外,TCP通信过程中所有数据报的 ACK 都为1,表示应答。
      • seq = v,v - 1 是B向A发送的最后一个字节的序号。
      • ack = u + 1 表示希望收到从第 u+1 个字节开始的报文段,并且已经成功接收了前 u 个字节。

      第二次挥手完成后,A到B方向的连接已经释放,B不会再接收数据,A也不会再发送数据。但B到A方向的连接仍然存在,B可以继续向A发送数据。

    • 第三次挥手
      当B向A发完所有数据后,向A发送连接释放请求,请求头:FIN = 1,ACK = 1,seq = w,ack = u+1。B便进入 LAST-ACK 状态。

    • 第四次挥手
      A收到释放请求后,向B发送确认应答,此时A进入TIME-WAIT 状态。该状态会持续 2MSL 时间,若该时间段内没有B的重发请求的话,就进入CLOSED状态,撤销TCB。当B收到确认应答后,也便进入CLOSED状态,撤销TCB。

为什么挥手是四次,而握手时三次?

握手时 ACK 和 SYN 可以放在一个报文里发送,但是关闭连接时,当收到对方的 FIN 报文,你未必完成所有数据,所以可能发送 ACK 确认收到 FIN,然后发送 FIN 表示关闭连接。