wiresharek 分析TCP 报文头

2024-06-02 11:38
文章标签 分析 tcp 报文 wiresharek

本文主要是介绍wiresharek 分析TCP 报文头,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文简单介绍了TCP面向连接理论知识,详细讲述了TCP报文各个字段含义,并从Wireshark俘获分组中选取TCP连接建立相关报文段进行分析。

一、概述

TCP是面向连接的可靠传输协议,两个进程互发数据之前需要建立连接,这里的连接只不过是端系统中分配的一些缓存和状态变量,中间的分组交换机不维护任何连接状态信息。连接建立整个过程如下(即三次握手协议):

首先,客户机发送一个特殊的TCP报文段;

其次,服务器用另一个特殊的TCP报文段来响应;

最后,客户机再用第三个特殊报文段作为响应。

图1 三次握手协议示意图[1]

二、TCP报文格式

2.1 概述

为了提供可靠的数据传输,TCP报文首部字段有较多的字段,TCP报文格式如下图:

图2 TCP报文格式

源和目标端口

用于多路复用/多路分解来自或送至上层应用的数据,可以这样理解,端口用来标识同一台计算机的不同进程。

序列号和确认号

这两个字段是TCP可靠传输服务的关键部分,序列号是该报文段首字节的字节流编号(TCP把数据看成是有序的字节流,TCP隐式地对数据流的每个字节进行编号)。这样理解可能更直观,当报文被分解成多个报文段时,序列号就是报文段首字节在整个报文的偏移量。确定号指定下一个期待的字节。TCP是全双工的,假设从主机A接收到主机B的数据,则主机A填充进报文段的确认号是主机A期望从主机B收到的下一个字节序号。还没理清这两者的关系?见下图(三次握手):

图3 正常情况下TCP连接建立过程

首部长度(4位)

因为选项是不定长的,这就需要标识整个首部字段的长度(单位是32位字),即5+选项个数。4位,单位是32位字,所以首部最长是15*4=60字节,即选项最长是40字节(10个选项)。

标志

URG

指示报文段里存在着被发送方的上层实体标记为”紧急”数据,当URG=1时,其后的紧急指针指示紧急数据在当前数据段中的位置(相对于当前序列号的字节偏移量),TCP接收方必须通知上层实体。

ACK

当ACK=0时,表示该数据段不包含确认信息,当ACK=1时,表示该报文段包括一个对已被成功接收报文段的确认。

PSH

当PSH=1时,接收方在收到数据后立即将数据交给上层,而不是直到整个缓冲区满。

RST

用于重置一个已经混乱的连接(如主崩溃),也可用于拒绝一个无效的数据段或者拒绝一个连接请求。一般而言,如果你得到的数据段被设置了RST位,那说明你这一端有问题了。

SYN

用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1

注:捎带是指对客户机到服务器数据的确认被装载在一个承载服务器到客户机的数据报文段中。

FIN

用于释放一个连接,表示发送方已经没有数据要传输了。此时,接收方可能继续接收数据,好在SYN和FIN数据段都有序列号,从而保证了这两种数据段以正确顺序被处理。

窗口大小

用于流控制(确保连接的任何一方都不会过快地发送过量的分组而淹没另一方),窗口大小指定了从被确认的字节算起可以发送多少个字节。

校验和

提供了额外可靠性,在计算检验和的时候,TCP的Checksum域设为0,如果数据域的字节数为奇数,则数据域填补一个额外的0字节。校验和算法:将所有的16位字按1的补码形式累加起来,取累加结果的补码。因此,当接收方执行同样计算时(包括Checksum域),结果应该是0。

紧急指针

参考标志字段的URG位。

选项

选项部分是为了适合复杂网络环境和更好地服务于应用层设计的。TCP选项最长是40字节。详情见2.2。

数据

无任何数据的TCP段也是合法的,通常用于确认和控制信息。

2.2 选项字段[2]

TCP选项部分很好出现在已经建立连接的会话中,只要出现在TCP连接建立阶段,即三次握手。TCP选项部分实际运用有以下几种:

(1)最大报文传输段(MMS, Maximum Segment Size)

用于发送发与接收方协商最大报文段长度(仅仅是净荷数据,不包括TCP首部字段)。TCP在三次握手中,每一方都会通告期望收到的MSS(MSS只出现在SYN数据包中),如果一方不接受另一方的MSS值,则使用默认的536字节净荷数据,即主机能够接受20+536字节的TCP报文段。

(2)窗口扩大选项(Window scaling)

TCP报文的窗口大小字段占16位,即最大值是65535,但随着时延和带宽比较大的通信产生(如卫星通信),需要更大的窗口满足性能和吞吐率,这就是窗口扩大选项存在的意义。例子见参考资料[2]。

Windows scaling占3个字节,最后一个字节是移位值(Shift count),即首部的窗口位数16向左移动,如移位值为14,则新的窗口最大值增大到65535*(2^14)。

窗口扩大选项是在TCP建立之初进行协商,如果已实现了窗口扩大,当不再需要扩大窗口时,发送移位值=0就可以恢复到原窗口大小,即65535。

(3)选择确认选项(SACK, Selective Acknowledgements)

考虑这样情况,主机A发送报文段12345,主机B收到135且报文无差错,SACK用来确保只重传缺少的报文段,而不是重传所有报文段。

SACK选项需要2个功能字节,一个用来指明使用SACK选项(SACK Permission),另一指明这个选项占多少字节。

那怎么形容丢失的报文段2,说明2的左右边界分别是1、3。TCP的数据报文是有字块边界的,而这种边界是由序列号表示的。

最多能指明多少个字节块的边界信息呢?答案是4个。这是因为选项字段最大是40字节,去除2个功能字节,序列号是32位即4字节,并且需要左右边界,所以(40-2)/8 = 4。

(4)时间戳选项(timestamps)

时间戳选项用来计算往返时间RTT,发送方在发送报文段时把当前时钟的时间值放入时间戳字段,接收方将该时间戳字段的值复制到确认报文中,当接收方收到确认报文,对比确认报文的时间戳(等于发送方发送报文段的时间戳)和现在的时钟,即可算出RTT。

时间戳选项还可用于防止回绕序号PAWS。序列号只有32位,每2^32个序列号就会回绕(想想环形队列),采用时间戳选项很容易区分相同序列号的报文段。

(5)NOP(NO-Operation)

TCP的头部必须是4字节的倍数,而大多数选项不是4字节倍数,不足的用NOP填充。除此之外,NOP也用于分割不同的选项数据,如窗口扩大选项和SACK之间使用NOP隔离(下面的实例将看到这一点)。

三、实例解析

3.1 概述

还是以访问百度首页为例,首先用DNS协议将URL解析成IP地址,接着在客户机和服务器间建立TCP连接,用Wireshark俘获的分组如下图:

图4 Wireshark俘获建立TCP连接分组

你一看会觉得有些奇怪,理论上应该是3个分组的,怎么有6个分组?先不急,先把这6个报文收发示意图作出来(结合时间和报文含义),如下:

图5 TCP连接建立实例

从图可知,连接建立伊始,客户机发了两个报文段,这也许是为了更快建立连接(假设有个请求报文段丢失,也不至于要等一段时间,重发报文)。接下来,以19、21、22(上图红色线条所示)分析TCP连接建立过程。

3.1 第一次握手19

Wireshark俘获TCP连接第一次握手的报文段如下:

图6 TCP连接第一次握手实例

这里主要挑几个字段分析:

标志字段,SYN=1、ACK=0表示该数据段没有使用捎带的确认域。

最大报文段长度(MMS)1460是怎么来的,链路层的以太网物理特性决定数据帧长度为1500(即MTU,最大传输单元),1460=1500-20(IP首部长度)-20(TCP首部长度)。不要被该报文首部长度32字节所迷惑,这只是建立连接过程。MSS与MTU关系见下图[2]:

图7 MSS与MTU关系

NOP字段,可以作为不足4倍数字节填充,也可作为选项间分隔,该报文段出现了3个NOP,具体功能见下图:

图8 TCP报文NOP字段

3.3 第二次握手21

服务器响应客户端TCP报文段,此时确认号为1了,SYN=1、ACK=1表明连接应答捎带一个确认,Wireshark俘获分组如下:

图9 TCP连接第二次握手实例

为什么MSS是1452而不是1460?这是因为使用PPPoE(Point-to-Point over Ethernet,可以使以太网的主机通过一个简单的桥接设备连到一个无端的接入集中器上[3])拨号上网,PPoP首部是8个字节,所以PPPoE的MTU是1492,MSS也就为1492-40=1452。

那么,TCP连接建立后数据传输的MSS是多少呢,1460 or 1452 or 536 ?我的理解是默认值536,这样理解对吗?求指点!

3.4 第三次握手22

客户机再次服务器的报文段,此时序列号和确认号都为1,没有选项字段,Wireshark俘获的分组信息如下:

图10 TCP连接第三次握手实例

值得注意的,因为窗口扩展大小协商未果,所以就不扩大窗口了,即窗口大小最大为65535。

如此,TCP连接建立:-)

这篇关于wiresharek 分析TCP 报文头的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

[职场] 公务员的利弊分析 #知识分享#经验分享#其他

公务员的利弊分析     公务员作为一种稳定的职业选择,一直备受人们的关注。然而,就像任何其他职业一样,公务员职位也有其利与弊。本文将对公务员的利弊进行分析,帮助读者更好地了解这一职业的特点。 利: 1. 稳定的职业:公务员职位通常具有较高的稳定性,一旦进入公务员队伍,往往可以享受到稳定的工作环境和薪资待遇。这对于那些追求稳定的人来说,是一个很大的优势。 2. 薪资福利优厚:公务员的薪资和

高度内卷下,企业如何通过VOC(客户之声)做好竞争分析?

VOC,即客户之声,是一种通过收集和分析客户反馈、需求和期望,来洞察市场趋势和竞争对手动态的方法。在高度内卷的市场环境下,VOC不仅能够帮助企业了解客户的真实需求,还能为企业提供宝贵的竞争情报,助力企业在竞争中占据有利地位。 那么,企业该如何通过VOC(客户之声)做好竞争分析呢?深圳天行健企业管理咨询公司解析如下: 首先,要建立完善的VOC收集机制。这包括通过线上渠道(如社交媒体、官网留言

打包体积分析和优化

webpack分析工具:webpack-bundle-analyzer 1. 通过<script src="./vue.js"></script>方式引入vue、vuex、vue-router等包(CDN) // webpack.config.jsif(process.env.NODE_ENV==='production') {module.exports = {devtool: 'none

Java中的大数据处理与分析架构

Java中的大数据处理与分析架构 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们来讨论Java中的大数据处理与分析架构。随着大数据时代的到来,海量数据的存储、处理和分析变得至关重要。Java作为一门广泛使用的编程语言,在大数据领域有着广泛的应用。本文将介绍Java在大数据处理和分析中的关键技术和架构设计。 大数据处理与

段,页,段页,三种内存(RAM)管理机制分析

段,页,段页         是为实现虚拟内存而产生的技术。直接使用物理内存弊端:地址空间不隔离,内存使用效率低。 段 段:就是按照二进制文件的格式,在内存给进程分段(包括堆栈、数据段、代码段)。通过段寄存器中的段表来进行虚拟地址和物理地址的转换。 段实现的虚拟地址 = 段号+offset 物理地址:被分为很多个有编号的段,每个进程的虚拟地址都有段号,这样可以实现虚实地址之间的转换。其实所谓的地

mediasoup 源码分析 (八)分析PlainTransport

mediasoup 源码分析 (六)分析PlainTransport 一、接收裸RTP流二、mediasoup 中udp建立过程 tips 一、接收裸RTP流 PlainTransport 可以接收裸RTP流,也可以接收AES加密的RTP流。源码中提供了一个通过ffmpeg发送裸RTP流到mediasoup的脚本,具体地址为:mediasoup-demo/broadcaste

MQTT之CONNECT控制报文详解

目录 1.  MQTT协议规范 2.  名词解释 3.  CONNECT控制报文详解 3.1  固定报头 Fixed header 3.2  可变报头 Variable header 3.2.1  协议名 Protocol Name 3.2.2  协议级别 Protocol Level 3.2.3  连接标志 Connect Flags 3.2.4  保持连接 Keep

Java并发编程—阻塞队列源码分析

在前面几篇文章中,我们讨论了同步容器(Hashtable、Vector),也讨论了并发容器(ConcurrentHashMap、CopyOnWriteArrayList),这些工具都为我们编写多线程程序提供了很大的方便。今天我们来讨论另外一类容器:阻塞队列。   在前面我们接触的队列都是非阻塞队列,比如PriorityQueue、LinkedList(LinkedList是双向链表,它实现了D

线程池ThreadPoolExecutor类源码分析

Java并发编程:线程池的使用   在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:   如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。   那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务?

ConcurrentHashMap之源码分析

集合是编程中最常用的数据结构。而谈到并发,几乎总是离不开集合这类高级数据结构的支持。比如两个线程需要同时访问一个中间临界区(Queue),比如常会用缓存作为外部文件的副本(HashMap)。这篇文章主要分析jdk1.5的3种并发集合类型(concurrent,copyonright,queue)中的ConcurrentHashMap,让我们从原理上细致的了解它们,能够让我们在深度项目开发中获益非浅