| |
|
开发:
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协议
TCP三次握手在客户端尝试与服务器连接之前,服务器必须首先绑定【bind】并监听【linten】一个端口以打开连接:这称为被动打开【passive open】。 一旦建立了被动打开【passive open】,客户端可以通过使用三次握手发起主动打开【active open】来建立连接:
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【窗口缩放】我们再前面介绍了,主要是用于拓展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地址范围 |
|
上一篇文章 查看所有文章 |
|
开发:
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- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |