【面试八股总结】传输控制协议TCP(二):报文段与流量控制

参考资料 :小林Coding、阿秀、代码随想录

一、TCP报文段首部

TCP 虽然是面向字节流的,但 TCP 传送的数据单元却是报文段

        一个 TCP 报文段分为首部和数据两部分,TCP 报文段首部的前 20 个字节是固定的,后面有 4n 字节是根据需要而增加的选项 (n 是整数)。

名称

含义

1

源端口和目的端口

  • 端口是运输层与应用层的服务接口。
  • 运输层的复用和分用功能都要通过端口才能实现。
  • 告诉主机报⽂段来⾃哪⾥,传给哪个上层协议或应⽤程序。

2

序号(序列号)

  • TCP 连接中传送的数据流中的每一个字节都有序号。
  • 序号字段的值则指的是本报文段所发送的数据的第一个字节的序号.

3

数据偏移

(首部长度)

  • 指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远。
  • “数据偏移”的单位是 32 位字(以 4 字节为计算单位)

4

确认号

  • 期望收到对方的下一个报文段的数据的第一个字节的序号。

5

URG(URGENT)

  • 当 URG = 1 时,表明紧急指针字段有效。
  • 告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。

6

ACK(Acknowledgment)

  • ACK = 0,确认号无效,ACK = 1,确认号有效

7

PSH (Push)

  • 接收方应该尽快将这个报文段交给应用层标志。
  • 接收 TCP 收到 PSH = 1 的报文段,就尽快地交付接收应用进程,而不再等到整个缓存都填满了后再向上交付。

8

RST (Reset)

  • 重置连接标志,当 RST=1 时,表明 TCP 连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。

9

SYN

(Synchronize)

  • 发起一个连接标志,同步 SYN = 1 表示这是一个连接请求或连接接受报文。
  • SYN攻击:伪造大量虚拟地址向目标主机发起连接
  • LAND攻击:目标地址与源地址都是目标主机,向目标主机发起连接

10

FIN (Finish)

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

11

Window 窗口

  • 指示发送端还能接收多少字节的数据,接收缓存大小。
  • 用来让对方设置发送窗口的依据,单位为字节。

12

Checksum

校验和

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

13

Urgent Pointer

紧急指针

  • 仅在URG标志被设置时才有效,用于指示紧急数据的末尾字节序号。指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面)。

14

选项字段

  • TCP 最初只规定了一种选项,即最大报文段长度 MSS。MSS 告诉对方 TCP:“我的缓存所能接收的报文段的数据字段的最大长度是 MSS 个字节。”
  • MSS (Maximum Segment Size)是 TCP 报文段中的数据字段的最大长度。数据字段加上 TCP 首部才等于整个的 TCP 报文段。所以,MSS是“TCP 报文段长度减去 TCP 首部长度”。

二、TCP流量控制

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

        流量控制 (flow control) 是为了控制发送方的发送速率,既要让接收方来得及接收,也不要使网络发生拥塞。利用滑动窗口机制可以很方便地在 TCP 连接上实现流量控制。

1.1 什么是窗口?

        TCP每发送⼀个数据,都需要⼀次应答,然后继续发送,为每个数据包都进行确认应答,缺点是:数据往返时间越长,网络吞吐量越低。为解决这个问题,TCP 引⼊窗口概念(首部Window字段)。即使在往返时间较长的情况下,它也不会降低网络通信效率。窗口大小是指无需等待确认应答,可以继续发送数据的最大值。

        窗口的实现是操作系统开辟的⼀个缓存空间,发送方主机在等到确认应答返回之前,必须在缓冲区中保留已发送的数据。如果按期收到确认应答,此时数据就可以从缓存区清除。

        如上图, 图中的 ACK 600 确认应答报文丢失,可以通过下一个确认应答进行确认,只要发送方收到了 ACK 700 确认应答,就意味着 700 之前的所有数据「接收方」都收到了。这个模式就叫累计确认或者累计应答

        通常窗口的大小是由接收方的窗口大小来决定的。发送方发送的数据大小不能超过接收方的窗口大小,否则接收方就无法正常接收到数据。

1.2 发送方滑动窗口

  • #1 是已发送并收到 ACK确认的数据:1~31 字节
  • #2 是已发送但未收到 ACK确认的数据:32~45 字节
  • #3 是未发送但总大小在接收方处理范围内(接收方还有空间):46~51字节
  • #4 是未发送但总大小超过接收方处理范围(接收方没有空间):52字节以后

        发送方将数据全部都发送后,可用窗口的大小就为 0 了,表明可用窗口耗尽,在没收到 ACK 确认之前是无法继续发送数据了。

        若收到之前发送数据的 ACK 确认应答后,如果发送窗口的大小没有变化,则滑动窗口往右边移动 k 个字节,因为有 k 个字节的数据被应答确认,接下来的 k 字节又变成了可用窗口。

1.3 接收方滑动窗口

  •  #1 + #2 是已成功接收并确认的数据(等待应用进程读取);
  • #3 是未收到数据但可以接收的数据;
  • #4 未收到数据并不可以接收的数据;

1.4 窗口关闭:

        TCP中采用滑动窗口进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以用于接收数据发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。当滑动窗口为0时,发送方一般不能再发送数据报。两种情况除外:

  1. 发送紧急数据;
  2. 发送方可以发送一个1字节的数据报通知接受方重新声明它希望接收的下一字节以及发送方滑动窗口大小。 

举个🌰:

        如上图,B 向 A 发送了零窗口的报文段后不久,B 的接收缓存又有了一些存储空间。于是 B 向 A 发送了 rwnd = 400 的报文段。但这个报文段在传送过程中丢失了。A 一直等待收到 B 发送的非零窗口的通知,而 B 也一直等待 A 发送的数据。如果没有其他措施,这种互相等待的死锁局面将一直延续下去。

        为了解决这个问题,TCP 为每一个连接设有一个持续计时器 (persistence timer)。只要 TCP 连接的一方收到对方的零窗口通知,就启动该持续计时器。若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带 1 字节的数据),而对方就在确认这个探测报文段时给出了现在的窗口值。

  • 若窗口仍然是零,则收到这个报文段的一方就重新设置持续计时器。
  • 若窗口不是零,则死锁的僵局就可以打破了。

2. 糊涂窗口综合症

可以用不同的机制来控制 TCP 报文段的发送时机:

  • 第一种机制是 TCP 维持一个变量,它等于最大报文段长度 MSS。只要缓存中存放的数据达到 MSS 字节时,就组装成一个 TCP 报文段发送出去。
  • 第二种机制是由发送方的应用进程指明要求发送报文段,即 TCP 支持的推送 (push) 操作。
  • 第三种机制是发送方的一个计时器期限到了,这时就把当前已有的缓存数据装入报文段(但长度不能超过 MSS)发送出去。

        糊涂窗口综合症是指每次仅发送一个字节或很少几个字节的数据时,有效数据传输效率变得很低的现象。

2.1 发送方糊涂窗口综合症

        发送方 TCP 每次接收到一字节的数据后就发送。这样,发送一个字节需要形成 41 字节长的 IP 数据报,效率很低。

解决方法:使用 Nagle 算法

Negle算法伪代码:

if 有数据要发送 {
    if 可用窗口大小 >= MSS and 可发送的数据 >= MSS {
    	立刻发送MSS大小的数据
    } else {
        if 有未确认的数据 {
            将数据放入缓存等待接收ACK
        } else {
            立刻发送数据
        }
    }
}
  • 若发送应用进程把要发送的数据逐个字节地送到 TCP 的发送缓存,则发送方就把第一个数据字节先发送出去,把后面到达的数据字节都缓存起来。
  • 当发送方收到对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去,同时继续对随后到达的数据进行缓存。
  • 只有在收到对前一个报文段的确认后才继续发送下一个报文段。
  • 当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度时,就立即发送一个报文段。

2.2 接收方糊涂窗口综合症

        当接收方的 TCP 缓冲区已满,接收方会向发送方发送窗口大小为 0 的报文。

        若此时接收方的应用进程以交互方式每次只读取一个字节,于是接收方又发送窗口大小为一个字节的更新报文,发送方应邀发送一个字节的数据(发送的 IP 数据报是 41 字节长),于是接收窗口又满了,如此循环往复。

解决方法:

        让接收方等待一段时间,使得接收缓存已有足够空间容纳一个最长的报文段,或者等到接收缓存已有一半空闲的空间。只要出现这两种情况之一,接收方就发出确认报文,并向发送方通知当前的窗口大小。

  • 30
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值