【面试八股总结】传输控制协议TCP(二)

2024-04-02 14:36

本文主要是介绍【面试八股总结】传输控制协议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 字节长),于是接收窗口又满了,如此循环往复。

解决方法:

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

这篇关于【面试八股总结】传输控制协议TCP(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/870243

相关文章

C# List.Sort四种重载总结

《C#List.Sort四种重载总结》本文详细分析了C#中List.Sort()方法的四种重载形式及其实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录1. Sort方法的四种重载2. 具体使用- List.Sort();- IComparable

SpringBoot项目整合Netty启动失败的常见错误总结

《SpringBoot项目整合Netty启动失败的常见错误总结》本文总结了SpringBoot集成Netty时常见的8类问题及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一、端口冲突问题1. Tomcat与Netty端口冲突二、主线程被阻塞问题1. Netty启动阻

SpringBoot整合Kafka启动失败的常见错误问题总结(推荐)

《SpringBoot整合Kafka启动失败的常见错误问题总结(推荐)》本文总结了SpringBoot项目整合Kafka启动失败的常见错误,包括Kafka服务器连接问题、序列化配置错误、依赖配置问题、... 目录一、Kafka服务器连接问题1. Kafka服务器无法连接2. 开发环境与生产环境网络不通二、序

python3中正则表达式处理函数用法总结

《python3中正则表达式处理函数用法总结》Python中的正则表达式是一个强大的文本处理工具,用于匹配、查找、替换等操作,在Python中正则表达式的操作主要通过内置的re模块来实现,这篇文章主要... 目录前言re.match函数re.search方法re.match 与 re.search的区别检索

Python版本与package版本兼容性检查方法总结

《Python版本与package版本兼容性检查方法总结》:本文主要介绍Python版本与package版本兼容性检查方法的相关资料,文中提供四种检查方法,分别是pip查询、conda管理、PyP... 目录引言为什么会出现兼容性问题方法一:用 pip 官方命令查询可用版本方法二:conda 管理包环境方法

pycharm跑python项目易出错的问题总结

《pycharm跑python项目易出错的问题总结》:本文主要介绍pycharm跑python项目易出错问题的相关资料,当你在PyCharm中运行Python程序时遇到报错,可以按照以下步骤进行排... 1. 一定不要在pycharm终端里面创建环境安装别人的项目子模块等,有可能出现的问题就是你不报错都安装

Python中logging模块用法示例总结

《Python中logging模块用法示例总结》在Python中logging模块是一个强大的日志记录工具,它允许用户将程序运行期间产生的日志信息输出到控制台或者写入到文件中,:本文主要介绍Pyt... 目录前言一. 基本使用1. 五种日志等级2.  设置报告等级3. 自定义格式4. C语言风格的格式化方法

Spring 依赖注入与循环依赖总结

《Spring依赖注入与循环依赖总结》这篇文章给大家介绍Spring依赖注入与循环依赖总结篇,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Spring 三级缓存解决循环依赖1. 创建UserService原始对象2. 将原始对象包装成工

MySQL中查询和展示LONGBLOB类型数据的技巧总结

《MySQL中查询和展示LONGBLOB类型数据的技巧总结》在MySQL中LONGBLOB是一种二进制大对象(BLOB)数据类型,用于存储大量的二进制数据,:本文主要介绍MySQL中查询和展示LO... 目录前言1. 查询 LONGBLOB 数据的大小2. 查询并展示 LONGBLOB 数据2.1 转换为十

Linux之UDP和TCP报头管理方式

《Linux之UDP和TCP报头管理方式》文章系统讲解了传输层协议UDP与TCP的核心区别:UDP无连接、不可靠,适合实时传输(如视频),通过端口号标识应用;TCP有连接、可靠,通过确认应答、序号、窗... 目录一、关于端口号1.1 端口号的理解1.2 端口号范围的划分1.3 认识知名端口号1.4 一个进程