05-传输层(4)

TCP报文段的首部格式

  • TCP 虽然是面向字节流的,但 TCP 传送的数据单元却是报文段
  • 一个 TCP 报文段分为首部和数据两部分,而 TCP 的全部功能都体现在它首部中各字段的作用。
  • TCP 报文段首部的前 20 个字节是固定的,后面有 4n 字节是根据需要而增加的选项 (n 是整数)。因此 TCP 首部的最小长度是 20 字节。


源/目的端口

  • 各占 2 字节
  • 端口是运输层与应用层的服务接口
  • 运输层的复用和分用功能都要通过端口才能实现

序号

  • 该字段也叫做 "报文段序号",特指本报文段所发送的数据的第 1 个字节的序号
  • 占 4 字节,序号范围 [0, 2^32 - 1];当序号增加到 2^32 - 1 后,下一个序号就又回到了 0
  • TCP是面向字节流的,在一个 TCP 连接中传送的字节流中的每一个字节都是按顺序编号
  • 整个要传送的字节流的起始序号必须在连接建立时设置

确认号

  • 占 4 字节
  • 是期望收到对方的下一个报文段的数据的第 1 个字节的序号
  • 若确认号 = N,则表明:到序号 N-1 为止的所有数据都已正确收到
  • 由于序号字段有 32 位长,可对 4GB 的数据进行编号,在一般情况下可保证当序号重复使用时,旧序号的数据早已通过网络到达终点

数据偏移

  • 即首部长度,占 4 位
  • 它指出 {TCP 报文段的数据起始处} 距离 {TCP 报文段的起始处} 有多远,实际上就是指出 TCP 报文段的首部长度
  • "数据偏移" 的单位是 32 位(以 4 字节为计算单位),因此数据偏移的最大值是 1111(B)x4=60 字节,这也是 TCP 首部的最大长度
  • 既然是以 4 字节为单位,那也就体现出了 "填充" 的意义

保留

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

紧急 URG

  • 当 URG = 1 时,表明紧急指针字段有效,即可在发送方 TCP 缓存中插队
  • 它告诉系统此报文段中有紧急数据,应尽快传送 (相当于高优先级的数据)

确认 ACK

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

推送 PSH (PuSH)

  • 接收方 TCP 缓存中插队
  • 接收方 TCP 收到 PSH = 1 的报文段,就尽快地(即"推送"向前)交付接收应用进程,而不再等到整个缓存都填满了后再向上交付

复位 RST (ReSeT)

  • 当 RST = 1 时,表明 TCP 连接中出现严重差错(如由于主机崩溃或其他原因),此时必须释放连接,然后再重新建立运输连接
  • RST 置 1 还用来拒绝一个非法的报文段或拒绝打开一个连接

同步 SYN

  • 在连接建立时,用来同步序号
    • SYN = 1,ACK = 0 连接请求-报文段
    • SYN = 1,ACK = 1 连接接受-报文段
  • 连接建立之后,SYN = 0

补充:SYN 攻击,伪造不存在的地址和 Server 建立会话

终止 FIN (FINish)

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

窗口

  • 占 2 字节,窗口值是 [0, 2^16 - 1] 之间的整数
  • 窗口字段明确指出了现在允许对方发送的数据量 // 也就是发送本报文段的一方的接收窗口
  • 窗口值经常在动态变化着,由 {接收窗口} 确定 {发送窗口}
    • 告诉对方,从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量(单位为字节)
    • 作为接收方让发送方设置其发送窗口的依据

检验和

  • 占 2 字节
  • 检验和字段检验的范围包括 首部 和 数据 这两部分
  • 在计算检验和时,要在 TCP 报文段的前面加上 12 字节的伪首部

紧急指针

  • 占 16 位
  • 仅在 URG = 1 时才有意义
  • 指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面)。因此,紧急指针指出了 {紧急数据的末尾} 在报文段中的位置
  • 注意,即使窗口值为 0 也可发发送紧急数据

选项(长度可变)

长度可变,最长达 40 字节。当没有使用"选项"时,TCP 的首部长度是 20 字节。选项有如下种类:

最大报文段长度

  • 最大报文段长度MSS (Maximum Segment Size),MSS 是 TCP 报文段中的 {数据字段} 的最大长度。
  • 数据字段长度 + TCP首部长度 = 整个的TCP报文段长度
  • 为什么要规定 MSS ?
    • MSS 与接收窗口值没有关系
    • 若选择较小的 MSS 长度,网络的利用率就降低。当 TCP 报文段只含有 1 字节的数据时,在 IP 层传输的数据报的开销至少有 40 字节(包括 TCP 报文段的首部和 IP 数据报的首部)。这样,对网络的利用率就不会超过 1/41。到了数据链路层还要加上一些开销。
    • 若选择很长的 MSS 长度,也不行。若 TCP 报文段非常长,那么在 IP 层传输时就有可能要分解成多个短数据报片。在终点要把收到的各个短数据报片装配成原来的 TCP 报文段。当传输出错时还要进行重传。这些也都会使开销增大。
    • 因此,MSS 应尽可能大些,只要在 IP 层传输时不需要再分片就行。
  • 由于 IP 数据报所经历的路径是动态变化的,因此在这条路径上确定的不需要分片的 MSS,如果改走另一条路径就可能需要进行分片。因此最佳的 MSS 是很难确定的
  • MSS 负责告诉对方 TCP:我的缓存所能接收的报文段的数据字段的最大长度是 MSS 个字节

窗口扩大

  • 占 3 字节,其中有一个字节表示 {移位值 S}
  • 新的窗口值等于 TCP 首部中的窗口位数增大到 (16 + S),相当于把窗口值向左移动 S 位后获得实际的窗口大小

时间戳

  • 占 10 字节
  • 其中最主要的字段时间戳值字段(4 字节)和时间戳回送回答字段(4 字节)

选择确认 SACK

【场景】若收到的报文段无差错,只是未按序号,中间还缺少一些序号的数据,那么能否设法只传送缺少的数据而不重传已经正确到达接收方的数据?

  • 接收方收到了和前面的字节流不连续的两个字节块。如果这些字节的序号都在接收窗口之内,那么接收方就先收下这些数据,但要把这些信息准确地告诉发送方,使发送方不要再重复发送这些已收到的数据。
  • RFC 2018 的规定
    • 如果要使用选择确认,那么在建立 TCP 连接时,就要在 TCP 首部的选项中加上“允许 SACK (Selective ACK)”的选项,而双方必须都事先商定好
    • 如果使用选择确认,那么原来首部中的“确认号字段”的用法仍然不变。只是以后在 TCP 报文段的首部中都增加了 SACK 选项,以便报告收到的不连续的字节块的边界
    • 由于首部选项的长度最多只有 40 字节,而指明一个边界就要用掉 4 字节,因此在选项中最多只能指明 4 个字节块的边界信息

填充

这是为了使整个首部长度是 4 字节的整数倍。

原文地址:https://www.cnblogs.com/liujiaqi1101/p/13628369.html