IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> TCP 三次握手 -> 正文阅读

[网络协议]TCP 三次握手

TCP协议

  • Source port【16位】【2字节】:标识发送端口
  • Destination port【16位】【2字节】:标识接收端口
  • Sequence number【32位】【4字节】:该字段具有双重作用
    • 如果Flags中的SYC位设置为1,那么这是初始序列号【initial sequence number】。实际第一个数据字节的序列号和相应ACK中的确认号就是这个序列号加1
    • 如果Flags中的SYC位设置为0,那么这是当前会话的该段【segment】的第一个数据字节的累积序列号
  • Acknowledgment number【32位】【4字节】:如果设置了Flags中的ACK标志,那么该字段的值就是ACK发送方所期望的下一个序列号。这表示收到了所有之前的字节(如果有的话)。每一端发送的第一个 ACK 确认另一端的初始序列号本身,但没有数据
  • Data offset【4位】:指定TCP报头的大小,以32位为单位。报头的最小大小是5个字【word】,最大是15个字【word】,因此最小为20字节,最大为60字节,允许在报头中放置多达40字节的可选项【options】。这个字段的名称来源于这样一个事实:它也是从TCP段【TCP segment】开始到实际数据的偏移量
  • Reserved【3位】:为将来使用,应设为零
  • Flags【9位】:包含9个位标志(控制位)
    • NS【1位】
    • CWR【1位】
    • ECE【1位】
    • URG 【1位】: 指示需要关注紧急指针【Urgent pointer】字段
    • ACK【1位】:指示需要关注确认【Acknowledgment?】字段。客户端在发送初始SYN报文之后所发送的所有报文都应该设置该标志
    • PSH 【1位】:推送功能。 请求将缓冲的数据推送到接收应用程序
    • RST 【1位】:连接复位/重置连接
    • SYN【1位】:同步序列号。只有从两端发送的第一个包才应该设置这个标志。
    • FIN【1位】:发送方的最后一个数据包
  • Window size【16位】【2字节】:接收窗口【?receive window】的大小,指定该段【段】的发送方当前愿意接受的窗口大小(参见流量控制和§窗口缩放)
  • Checksum 【16字节】【2字节】:16位的校验和【checksum】字段用于TCP报头、有效负载和IP伪报头的错误检查。伪报头由源IP地址、目的IP地址、TCP协议号(6)和TCP报头长度和有效负载(字节)组成
  • Urgent pointer【16位】【2字节】:如果设置了URG标志,那么这个16位字段是表示最后一个紧急数据字节的序列号的偏移量
  • 如果设置了 URG 标志,则该 16 位字段是与指示最后一个紧急数据字节的序列号的偏移量。
  • Options 【0 ~ 320 位,32位对齐】
  • Padding【None】:TCP 报头填充用于确保 TCP 报头在 32 位边界上结束,数据开始。填充由0组成。

TCP三次握手

在客户端尝试与服务器连接之前,服务器必须首先绑定【bind】并监听【linten】一个端口以打开连接:这称为被动打开【passive open】。 一旦建立了被动打开【passive open】,客户端可以通过使用三次握手发起主动打开【active open】来建立连接:

  1. SYC :主动打开是由客户端向服务器发送SYN来执行的。客户端将TCP段的序列号【Sequence number】设置为一个随机值 A
  2. SYN-ACK :作为响应,服务器以SYN-ACK作为响应。确认号【Acknowledgment number】设置为比接收到的序列号【Sequence number】多 1,即 A+1,同时,服务器为数据包选择的序列号【Sequence number】是另一个随机数 B
  3. ACK:最后,客户机向服务器发送一个ACK。序列号【Sequence number】设置为接收到的确认号【Acknowledgment number】,即 A+1,并且确认号【Acknowledgment number】设置为比接收到的序列号【Sequence number】多 1,即 B +1

TCP三次握手抓包

① SYN包

我们先拆解TCP包

?因为SYNC包没有数据体,所有TCP包只有报头,我们层层拆解

图中高亮部分,就是发送端口,即博主本机的端口,53620,我们请求www.baidu.com时只并未指定使用哪个端口与对端连接,此时,会默认选择一个随机可用的端口号来通信。

图下方高亮了对应于发送端口的16进制编码值:d1 74,解析为二进制为11010001 01110100,对应的10进制值则为53620

?图中高亮部分,就是接收端口,即对端端口,443,报头中对应的16进制编码值为:01 bb,解析为二进制为00000001 10111011,对应的10进制值则为443

?图中高亮部分,就是序列号【Sequence number】,共计32位,因为我们现在解析的是SYC包,客户端会随机初始化一个序号放到报头中。

16进制编码值为:73 9a e9 b5

?2进制编码值为:01110011 10011010 11101001 10110101

10进制编码值为:1939532213

图中高亮部分,就是确认号【Acknowledgment number】,共计32位。因为我们现在解析的是SYC包,没有确认目的,所以确认号为0

16进制编码值为:00 00 00 00

?2进制编码值为:00000000 00000000 00000000 00000000

10进制编码值为:0

?

?图中高亮部分,就是数据偏移【Data offset】,共计4位,高亮的具体16进制编码值并不准确,我们拆解一下

16进制编码值为:80

?2进制编码值为:1000 0000

? ? ? ? ? ? ? ? ? ? ? ? ? 【数据偏移取前4位】1000

? ? ? ? ? ? ? ? ? ? ? ? ? 【保留位取之后3位】000

? ? ? ? ? ? ? ? ? ? ? ? ? 【NS取末位】0

10进制编码值为:128

? ? ? ? ? ? ? ? ? ? ? ? ? 【数据偏移取前4位】8

? ? ? ? ? ? ? ? ? ? ? ? ? 【保留位取之后3位】0

? ? ? ? ? ? ? ? ? ? ? ? ? 【NS取末位置】0

具体什么含义呢,数据偏移标识的是从TCP段头开始,偏移多少,就是数据载荷的起始字节。

因为数据偏移【Data offset】,其真实10进制值为8,按照TCP协议规范,该字段是以32位的字为单位,亦即:32bit * 8 = 256bit = 32B

而由于SYC报文中没有数据载荷,所以该数据偏移应该等于TCP报文头总长度。

我们回头看最开始的那一张SYC报文总览接截图,高亮部分总计32字节。完美匹配!!

数据偏移【Data offset】之后尾随的是3位保留位【Reserved】,用于未来拓展,目前全部填充0

?图中高亮部分,就是Flags标志位,共计9位,根据TCP协议规范,我们拆解报文编码:

16进制编码值为:80 02

?2进制编码值为:1000 0000

? ? ? ? ? ? ? ? ? ? ? ? ? 【数据偏移取前4位】1000

? ? ? ? ? ? ? ? ? ? ? ? ? 【保留位取之后3位】000

? ? ? ? ? ? ? ? ? ? ? ? ? 【NS取末位】0

? ? ? ? ? ? ? ? ? ? ? ? ? ? 0000 0010

? ? ? ? ? ? ? ? ? ? ? ? ? 【CWR】0

? ? ? ? ? ? ? ? ? ? ? ? ? 【ECE】0

? ? ? ? ? ? ? ? ? ? ? ? ? 【URG】0

? ? ? ? ? ? ? ? ? ? ? ? ? 【ACK】0

? ? ? ? ? ? ? ? ? ? ? ? ? 【PSH】0

? ? ? ? ? ? ? ? ? ? ? ? ? 【RST】0

? ? ? ? ? ? ? ? ? ? ? ? ? 【SNC】1????????????????????????

? ? ? ? ? ? ? ? ? ? ? ? ? 【FIN】0

报头中Flags标识位符合TCP中协议的规定,SYNC包中,SYNC位置1,且序列号有值,确认号无值,其他置0

?图中高亮部分,指定的是接收窗口大小,即TCP协议规范中的Windows Size报头。

那么什么是接收窗口?

What Window Size

简单地说,它是一个TCP接收缓冲区,用于接收应用程序尚未处理的传入数据。

TCP接收窗口的大小使用TCP报头的Windows Size值字段与链接伙伴通信。该字段告诉链接伙伴在收到确认信息之前可以在线路上发送多少数据。如果接收方不能在数据到达时快速处理数据,接收缓冲区将逐渐被填满,并且确认包【acknowledgment packets】中的 TCP 窗口将减小。这将提醒发送方它需要减少发送的数据量或允许接收方有时间清除缓冲区。

在上面的图表中,客户端和服务器在通信时发布了它们的窗口大小值。每个TCP报头将显示最近的窗口值,该值可以随着连接的进展而增长或收缩。在这个例子中,客户端有一个65,535字节的TCP接收窗口,而服务器的接收窗口是5,840字节。对于许多应用程序来说,由于客户机倾向于接收数据而不是发送数据,因此客户端通常具有较大的分配窗口大小。握手后,客户端向服务器发送一个HTTP GET请求,该请求被快速处理。来自服务器的两个响应包到达客户端,客户端发送确认包以及更新的窗口大小。 客户端能够尽快处理来自 TCP 缓冲区的数据包,因此窗口大小没有减少。 客户端仍然有一个完整的窗口可用于接收数据——65,535 字节。

在另一个示例中,客户端正在从服务器请求数据并开始接收数据。但是,在这种情况下,客户端不能快速处理传入的数据。TCP缓冲区开始被填满,正如减少的窗口值所指示的那样。

来自客户端的确认包表明窗口正在收缩。只要窗口值没有降到零,最终用户就不会注意到这种行为。虽然数量略有减少,但缓冲区中仍然有足够的空间继续进行数据传输。 在很多情况下,客户端可以追赶并处理缓冲区外的数据,清除窗口并增加窗口值。

TCP Window Scale

为窗口大小分配的TCP报头值是两个字节长。这意味着接收窗口的最大可能数值是65,535字节。在今天的网络中,这个窗口大小不足以提供最佳的流量,特别是在长而胖的网络(具有高带宽和高延迟的链接)上。在它的原生状态下,TCP不能利用这些高性能链接,因为它一次只能发送最多65,535个字节。

因此,在RFC 1323中引入了TCP Options,使TCP接收窗口以指数方式增加。具体的功能称为TCP窗口缩放【TCP Window Scaling】,在握手过程中发布。当发布其接收窗口时,客户端或服务器也将发布将在连接的生命周期中使用的缩放因子(乘数)。

?在上图中,这个数据包的发送方正在发布一个64,240字节的TCP窗口,并且使用了一个4的缩放因子。这意味着真正的窗口大小是64,240?x 256(16,445,440字节)。使用缩放窗口允许端点发布超过1GB的窗口大小。要使用窗口缩放,连接的双方都必须在握手过程中宣传这种功能。如果一方或另一方不能支持缩放,那么双方都不会使用这个函数。缩放因子,或乘数,只会在握手期间在SYN包中发送,并将在整个生命周期中使用。

What Is a Zero Window?

当客户端(或服务器——但通常是客户端)发布其窗口大小为零的值时,这表明TCP接收缓冲区已满,不能再接收任何数据。它可能有一个被卡住的处理器或忙于其他任务,这可能会导致TCP接收缓冲区被填满。零窗口也可能是由于应用程序中没有检索TCP缓冲区的问题造成的。

来自客户端的 TCP 零窗口将停止来自服务器端的数据传输,从而为问题站清除其缓冲区留出时间。 当客户端开始消化数据时,它会通过发送 TCP窗口更新包【TCP Window Update packet】让服务器知道恢复数据流,该包中将会通告增加的窗口大小并且流将恢复。

图中高亮部分属于TCP协议规范中的校验和部分,共计2字节,16位。

图中高亮部分属于TCP协议规范中紧急指针【Urgent pointer】部分,只有当Flags标志位中的URG标志置1时,紧急指针【Urgent pointer】才有效。

#### ????

TCP提供了将某些字节的数据标记为“紧急”的能力。该特性允许应用程序处理和转发任何必须立即处理的数据,而不必将数据放在发送队列中进行处理。相反,数据被打包成一个段,在TCP报头中设置紧急标志,并在紧急指针字段中指定一个字节偏移量,标记紧急数据的结束。

需要注意的是,紧急指针【Urgent pointer】不使用序列号来指定紧急数据的结束,而是使用偏移量,指示紧急数据结束的位置。 启用了紧急标志的 TCP 段的接收者必须将紧急指针中提供的值加到当前段的序列号字段的值上,并使用结果值来确定结束序列号。 这意味着紧急指针偏移量可以引用另一个 TCP 段中的字节位置,允许紧急数据在需要时跨越多个段。

这种机制反映了 RFC 1122 中规定的特定设计。不幸的是,这种设计并不总是很清楚,许多 TCP 实现采取了不同的解释。 最值得注意的是,许多基于 BSD 的系统使用紧急指针来引用紧急指针中指定的偏移量之后的字节,而不是指定的

#### ????

当应用程序将数据流发送到TCP时,可能会有一些字节流,应用程序希望远程主机的应用程序以某种特殊的方式来处理这些字节。因此,TCP发送端创建一个段【Segment】,并将“紧急数据”放在段的开头,然后是正常数据。URG指针字段标识“紧急数据”的结束偏移量,因此接收主机可以识别它们。

图中高亮部分,是TCP报文的Options 部分,其中比较常用的两个可选配置为:

  • Windows scale 窗口缩放
  • MSS

Windows scale【窗口缩放】我们再前面介绍了,主要是用于拓展Windows Size的。

下面着重介绍MSS,以及经常提到的MTU。

MTU

最大传输单元(MTU)是以八位字节(8位字节)指定的,可以在基于包【packet】或帧【frame】的网络(如因特网)中发送的最大数据包或帧大小。互联网的传输控制协议(TCP)使用MTU来确定任何传输中每个包的最大大小。MTU通常与以太网协议相关联,在以太网协议中,1500字节的数据包是允许的最大数据包。

与MTU相关的最常见问题之一是,有时更高级别的协议可能会创建比特定链路所支持的包更大的包,您需要进行调整以使其工作。

为了解决这个问题,IPv4允许分片【fragmentation】,将数据报【datagram】分成若干片【pieces】。使用为该接口配置的MTU参数,每一块都足够小,可以通过它正在分片的单个链路。这种分片过程发生在IP层(OSI第3层),并将它分片的包标记为IP层。这确保目标主机的IP层知道它应该将数据包重新组合成原始数据报。

应用程序有时不支持分片【fragmentation】,如果可能的话,我们应该避免这种情况。避免分片的最好方法是调整最大段大小【maximum segment size】或TCP的 MSS,以便段在到达数据链路层之前调整其大小。

?如前所述,internet中MTU的常用值是1500字节。

如上图所示,MTU是由有效负载【payload】(也称为数据)、TCP头【TCP header】和IP头【IP header】构成的,其中,TCP头【TCP header】和IP头【IP header】各20个字节,共计40字节,每个包必须包含这40字节,这就为我们的数据留下了1460字节。

MSS

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章           查看所有文章
加:2021-07-30 13:06:15  更:2021-07-30 13:08:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:20:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码