第五章 传输层

#计算机网络 #应试笔记与八股

5.1 传输层提供的服务

5.1.1 传输层的功能

在OSI七层模型中,传输层位于表示层和传输层之间。对于通信来说,传输层是最高层;对于用户来说,传输层是最底层。非主机的网络设备(如路由器、网关)通常不涉及传输层的协议和功能,通常只有主机才涉及传输层的相关协议和功能。其主要功能如下:

  1. 为进程与进程之间提供逻辑通信。
  2. 复用和分用:
    1. 复用:应用层的所有应用进程都可以通过传输层传输到应用层
    2. 分用:传输层从网络层接收到的数据会交付给对应的应用进程(通过端口绑定应用)
  3. 对网络层进行报文差错检测,可以可选地提供可靠传输。

其主要协议有:

  1. TCP协议(Transmission Control Protocol):
    • 面向连接传输控制协议
    • 传输数据需要建立连接
    • 接收方在收到数据后需要确认
    • 不提供广播或多播服务
    • 可靠,时延高
  2. UDP协议(User Datagram Protocol):
    • 是无连接的用户数据报协议
    • 传输数据报前不需要建立连接
    • 接收端收到数据报后也不需要任何确认
    • 提供广播或多播服务
    • 不可靠,时延低

5.1.2 传输层的寻址与端口

端口号的划分(属于约定,不具有强制力):
端口号主要按范围进行划分,大致如下:
1. 服务端使用的端口号:范围[0, 49151],具体划分如下:
1. 熟知端口号:[0, 1023],主要分配给重要重要的应用程序,常见程序分配表如下:
Pasted image 20240317161802.png
2. 登记端口号:[1024, 49151]
2. 客户端使用的端口号:范围[0, 65535],在客户端程序运行时动态随机分配

在程序设计时,通常用套接字绑定IP地址和端口号(套接字,socket,意译为插槽)。

5.2 UDP协议

5.2.1 UDP数据报

UDP只是在IP数据报服务上提供了传输层的基本功能(即为进程提供socket逻辑通信,提供复用和分用),其特点为:

  1. UDP无连接,减少开销和时延
  2. UDP和网络层一样尽最大努力交付,不保证可靠交付,即不可靠传输
  3. UDP是面向报文的,只添加了一个很小的分组首部(8 Byte),对应用层报文既不合并又不拆分一次发送一个完整报文,需要应用自行分片,也适合一次传输少量数据
    Pasted image 20240317163923.png
  4. UDP无拥塞控制,适合实时性应用(即使网络拥塞,发送方依旧恒定速率发送)

UDP的首部格式:
UDP首部只有8 Byte,只存了源端口、目的端口、UDP长度(为整个UDP报文长度)。源IP和目的IP在IP数据报中。UDP包可以不要数据段,长度最少为8
Pasted image 20240317165313.png
当找不到目的端口时,则UDP数据报会被丢弃,并发送ICMP端口不可达差错报文
当UDP检验和校验错误,则UDP数据报会被丢弃。

5.2.2 UDP校验和

UDP在生成校验和时,会生成一个伪首部该伪首部相似于IP数据报报头但不同于IP数据报该伪首部只参与校验和计算不参与传输
Pasted image 20240317170318.png
校验和适用二进制反码求和再反码(会检验数据部分),具体计算规则如下:
1. 各二进制位正常求和,正常溢出
2. 若最高位产生溢出,则再原基础上再加 1
Pasted image 20240317170544.png
在发送时,上图UDP首部中校验和位设置为0后再计算,计算结果填充回原校验和位。
在接收时,直接进行计算若最后计算结果全1则校验成功

5.3 TCP协议

5.3.1 TCP协议的特点

TCP的特点主要有:

  1. 是面向连接(虚链接)的传输层协议
  2. 每一条TCP连接只能有两个端点,即点对点连接
  3. TCP提供可靠交付服务,可以使报文段无差错不丢失不重复按顺序到达。
  4. TCP可以提供全双工通信,有发送缓存和接收缓存:
    1. 发送缓存:
      • 缓存准备发送的数据
      • 缓存已发送但未收到确认的数据
    2. 接收缓存:
      • 缓存按序到达但尚未被应用程序接收的数据
      • 缓存未按序到达的数据
  5. TCP面向字节流,TCP在传输交付来的数据时会将数据看成一个无结构的二进制字节流。
  6. 采用C/S模式。

5.3.2 TCP报文段

TCP报文段的结构如下:
Pasted image 20240317174203.png
各字段结构如下:

  1. 源端口
  2. 目的端口
  3. 序号:TCP数据部分的第一个字节在该TCP连接所发送的所有字节中的序号。建立连接或释放连接使用的特殊报文段(SYN/FIN)或不携带数据的TCP报文段也要消耗一个序号。不携带数据的TCP报文段通常被当做Keep-Alive信号。ACK不占用序号
  4. 确认号:为接收方在收到该数据报之后的应答号,当接受方应答该号则表示该号之前的所有报文均接收完毕可以传输该确认号对应的报文段,通常为序号+数据段长度。
  5. 数据偏移字段:又叫报文头部长度字段,该TCP数据段的起始处距离该报文的起始段有多少偏移量(因为TCP首部长度可变,有选项字段),相当于TCP首部长度,以4 Byte为单位。
  6. 控制位:
    1. URG :urgent,表示该报文要紧急传输,不用在发送缓存中排队,要配合紧急指针使用紧急数据报不需要排队,直接交由操作系统发送该特性并不常用,只要有一个程序使用大家都会使用,最后效果是大家都没用。另外一个原因是由于实现不同,特性可能也不同。
    2. ACK :确认位,只有 ACK=1确认号才有效,才开启TCP确认机制。
    3. PSH :push,要求接收方尽快接收该数据,不用在接收缓存中排队。
    4. RST :复位,表示TCP中出现了严重差错(例如建立连接过程中序号计算出错),必须重新建立连接,也可以用于拒绝一个非法报文段,或拒绝打开连接。
    5. SYN :同步位,表示是请求建立连接的报文。
    6. FIN :finish,表示报文传输完毕,要求释放连接。
  7. 窗口字段:16位,范围[0, 65535]表示发送方或接收方的发送/接收窗口有多大,以便于双方同步缓存大小。该值的含义是发送方已经发送但未收到确认的数据帧的总大小,而非接收队列大小数据报数据段大小。该值允许发送方和接收方之间动态调节。TCP并没有提供数据段长度的标志位,其需要通过IP数据段长度减去偏移量获得
  8. 校验和:检验首部部分和数据部分,也有伪首部,规则同UDP,只有协议字段不同。
  9. 紧急指针:本紧急报文的数据字段的起始位置,只有 URG=1 时有意义。但是序号字段也可以确定偏移量...
    [TODO 似乎有点问题,建议找TCP规范核实]
    问题:
  10. 紧急数据报可以携带普通数据吗
    1. 如果可以携带,那紧急数据的偏移量可以和普通数据的偏移量不连续吗,比如我紧急数据的偏移量是4096,普通数据的偏移量是1024。
      1. 如果可以不连续,那现在可以用来标记的字段有且仅有 序号数据偏移紧急指针 ,那如何同时标记 报文中紧急数据起始地址报文中普通数据起始地址紧急数据偏移量4096普通数据偏移量1024
      2. 如果不可以不连续,那携带普通数据的意义是?为什么 数据偏移 只用4位就可以确定 报文中普通数据起始地址 ,而 紧急指针 却要用16位来确定 报文中紧急数据起始地址
    2. 如果不可以携带,那 序号 就可以标记紧急数据的偏移量,紧急指针是干什么的?

5.3.3 TCP连接管理

TCP连接有如下三个阶段:

  1. 建立连接
  2. 数据传送
  3. 连接释放
    其中,连接只能由客户端发起,服务端要提前开始监听。

先确定几个基本设定:

  1. TCP支持ACK功能,接收方在收到报文后应当对报文进行ACK来确保可靠性。TCP连接建立和释放的大多数操作都需要ACK应答
  2. ACK报文不是紧急报文但是会使用一些特殊机制使其插队发送
  3. ACK应答不会改变序号。
  4. 所有ACK报文的TCP帧头均有ACK位,尽管ACK(帧)不需要ACK(应答)。

TCP连接的建立
TCP连接的建立主要经过以下三个过程:
Pasted image 20240317201122.png
1. 客户端向服务端发送连接请求报文段无数据荷载。各标志位参数为:
SYN = 1 ,表示是连接请求报文段
序号 = xx初始序列号(ISN,客户端随机生成,预防序列号预测攻击)
ACK = 0字段不使能因为客户端此时不知道服务端分配的序号
2. TCP服务端为该连接准备分配缓存和变量,随后发送确认报文段无数据荷载,表示允许连接。各参数标志位为:
SYN = 1 ,表示为确认报文段
序号 = yy 为随机数(服务端随机生成)
ACK = 1 ,确认位使能。
确认号 = x + 1确认报文段也要占用一个序号,故加一
3. 客户端收到允许连接通知,并对该通知进行确认,可以携带数据荷载并传输数据,若不携带荷载则为一个普通空包,可以当做一个 Keep Alive 信号。各标志位与再发一个"空包"意义相同,为:
SYN = 0
序号 = x + 1
ACK = 1
确认号 = y + 1
注意,HTTP协议中所使用的TCP连接在第三次握手时就会发送请求报文
因此TCP连接的三次握手可以直接理解为一次申请、一次同意、一次TODO。

SYN泛洪攻击
服务端在收到客户端发出的连接请求报文段(SYN=1)后服务器都需要为其进行分配资源,而TCP客户端直到收到确认报文段(SYN=1)后才会分配资源,因此利用此方式进行的攻击就叫SYN泛洪攻击。
通常使用SYN Cookie解决SYN泛洪攻击。

TCP连接的释放
在TCP标准RFC 793中,关闭TCP的意思为 "I have no more data to send."。
并且规定了以下预期效果(因为TCP是全双工通信):
1. 申请关闭的用户可以继续接收数据直到对方也申请关闭
2. 发送者在收到对方的关闭信号后,仍然会可靠地把缓冲区中未发送的数据可靠地传输到接收方那里当发送者这边接收到连接断开的提示时也就意味着接受着成功的收到了发送者缓冲区中所有待发送的信息。而接受者在关闭TCP后也必须持续接收发送者缓冲区未发送完的数据。在上述要求下:
1. 发送者收到接受者的FIN报文后,会构造一个FIN报文并安排到待发送队列的末尾并拒绝新的信息入队(并发送ACK响应该FIN报文避免重传)。(因此FIN报文通常不是紧急报文)
2. 发送者的FIN报文在自己的发送队列上发送完毕后,会等待接受者的ACK响应。若超时未响应,则会告知用户。随后回收资源。
3. 简单来说,TCP连接的释放就是允许将全双工的TCP先关闭为单工再完全关闭
在上述预期效果的背景下再去了解和学习四次挥手会好一些。
TCP的释放的四次挥手主要有以下四个阶段:
Pasted image 20240317204245.png
1. 当一方选择关闭连接时(记作A),发送连接释放报文通常不携带数据同时停止发送数据,但是保持数据的接收(因为对方缓冲区中可能还有数据)。各标志位为:
FIN = 1 ,表示是连接释放报文,又叫FIN报文。
ACK = 1 ,当然需要ACK。
序号 = u ,序号该是多少就是多少。
2. 另外一方(记作B)收到连接释放报文后,发送该报文的ACK应答,避免重复发送。注意由于ACK的特殊机制其会比B的发送缓冲区中未被发送的数据先发送。随后B将自己的FIN报文放到自己的发送队列末尾,并拒绝新报文进入队列。在进入环节3之前,FIN之前的所有未发送报文均会被正常发送(但此步骤通常不单独讨论)。该ACK帧的各标志位为:
ACK = 1 ,我也不明白不需要ACK的ACK为什么要加ACK,但是ACK都要加ACK。
序号 = v该序号会在发送完缓冲区队列后变为 w - 1
确认号 = u + 1 ,确认号正常计算。
3. FIN帧在B的队列中到达队头,FIN帧从B中发送。各标志位为:
FIN = 1
ACK = 1 ,需要应答。
序号 = w ,序号正常计算。
确认号 = q + 1 ,确认号正常计算。
4. A应答B的FIN帧。各标志位为:
ACK = 1
序号 = u + 1 ,序号正常计算。
确认号 = w + 1 ,确认号正常计算。
最后申请关闭连接的A要等待两个最长报文段确保最后一个ACK正确送达(无论发什么报文都要等待两个最长报文段,超时则重传)。
四次挥手中,其中有两次都是ACK应答。而ACK应答无论发送什么报文都要ACK,实际上关键挥手共计两次。

5.3.4 TCP可靠传输

可靠传输:
可靠传输要求接收方接收到的字节流与发送方发出的字节流完全一致。

TCP实现可靠传输的机制主要有:

  1. 校验
  2. 序号
  3. 确认:TCP每传一个数据报文都需要接收方确认
  4. 重传:当超过重传时间未收到确认,则发送方会重传(TCP协议内置自适应算法,动态改变加权平均往返时间RTTs)

冗余ACK机制:
每当一个比期望序号大的失序报文段到达,接收方都会发送一个冗余ACK来表示其期待的下一顺序字节。
该机制有助于催促发送方快速重传。

5.3.5 TCP流量控制

重新回忆一下流量控制与拥塞控制的区别:
  • 拥塞和流量控制的区别:
    1. 拥塞是指所有节点都来不及接收分组导致的需要丢弃大量分组的网络状态,是全局性的状态,一般由网络负载过重引起。
    2. 流量控制是指当发送方发送速率太快,接收方来不及接受时所需要进行的操作。
    • 其实现方法主要有:
      1. 开环控制(静态控制方法)
      2. 闭环控制(动态控制方法)
回忆发送窗口的概念:
发送窗口是指发送方已经发送但未收到确认的数据帧的总大小
  1. 窗口字段:16位,范围[0, 65535]表示发送方或接收方的发送/接收窗口有多大,以便于双方同步缓存大小。该值的含义是发送方已经发送但未收到确认的数据帧的总大小,而非接收队列大小数据报数据段大小。该值允许发送方和接收方之间动态调节。TCP并没有提供数据段长度的标志位,其需要通过IP数据段长度减去偏移量获得

TCP实现流量控制使用滑动窗口机制实现,具体方法为:

  1. 接收方会根据自己接收缓存的大小通过窗口字段动态调整发送窗口的大小。
  2. 发送方在收到接收方设置的窗口字段后,会选取接收窗口和拥塞窗口的最小值来设置发送窗口
  3. 在不考虑丢包的情况下,发送窗口可以理解为在链路上奔波的总的数据报文大小。发送窗口可以被设置为0,当设置为0后,发送方会使用计时器定时使用探测报文段探测对方设置的窗口大小从而打破死锁局面。

5.3.6 [TODO]拥塞控制