《熬夜整理》保姆级系列教程-玩转Wireshark抓包神器教程(7)-Wireshark的TCP包详解-上篇

1.简介

上一篇中通过宏哥的介绍和讲解,小伙伴或者童鞋们应该知道宏哥今天要讲解和介绍的内容在哪里了吧,没错就是介绍那个OSI七层模型的传输层。因为只有它建立主机端到端的连接如:TCP、UDP。

2.TCP是什么?

tcp是工作在传输层,也就是网络层上一层的协议。

它是面向连接的,可靠的,基于字节流、全双工的通信协议。

TCP收到上一层的数据包后,会加上TCP头并且进行一些特殊处理后,再传递给网络层。

2.1TCP定义

传输控制协议(英语:Transmission Control Protocol,缩写:TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能。用户数据报协议(UDP)是同一层内另一个重要的传输协议。

3.TCP理论

TCP提供了一种面向连接的、可靠的字节流服务。

面向连接:接双方在通信前需要预先建立一条连接,这犹如实际生活中的打电话。

  • 应用数据分割成TCP认为最适合发送的数据块。
  • 重传机制。设置定时器,等待确认包
  • 对首部和数据进行校验
  • TCP对收到的数据进行排序,然后交给应用层
  • TCP的接收端丢弃重复的数据
  • TCP还提供流量控制

TCP连接必须要经历三次握手,而释放一个TCP连接需要四次握手,这是由TCP的半关闭特性造成的。因为TCP连接时全双工的,因此,需要TCP两端要单独执行关闭。值得注意的是,主动关闭的一端在发送FIN之后,依然还能正常接收对方的数据,只是通知对方它已经没有数据需要发送了,同理,被动关闭的一端在收到FIN之后,仍然可以发送数据,直到它自身同样发出FIN之后,才停止发送数据。

4.什么是面向连接、无连接?

  • 面向连接:面向连接的协议要求发送数据前需要通过一种手段保证通信双方都准备好了,之后才进行通信。
  • 无连接:无连接的协议则不需要,想发就发

5.什么是全双工

全双工(Full Duplex)是一种通信方式,指通信的双方可以同时发送和接收数据,而不需要像半双工那样在发送和接收之间切换。在全双工通信中,数据可以在两个方向上同时传输,因此通信速度更快,效率更高。

6.OSI和封包详细信息的对应

为了更加清楚明白,宏哥这里将上一篇文章中的图拿过来进行说明和讲解。

7.TCP包的具体内容

从下图可以看到wireshark捕获到的TCP包中的每个字段。

8.TCP报文格式

TCP是面向连接、可靠的传输协议,其报文格式较复杂。TCP报文的格式如下:

上图简化如下:

注意:实际的TCP报文段会根据TCP头部长度和可选项的不同而有所变化。

复制代码
|  源端口(16位)  |  目的端口(16位)  |
|   序号(32位)   |
| 确认序号(32位) |
|  数据偏移(4位) | 保留(6位) | 标志位(6位) | 窗口大小(16位) |
| 校验和(16位)   |  紧急指针(16位)  |
|   选项(可选)   |
|   数据(可选)   |

主要字段解释:

  • 源端口:占 2 字节,标识数据包是哪个应用发出去的。

  • 目的端口:占 2 字节,标识数据包是发给哪个应用的。Source Port和Destination Port:分别占用16位,表示源端口号和目的端口号;用于区别主机中的不同进程,而IP地址是用来区分不同的主机的,源端口号和目的端口号配合上IP首部中的源IP地址和目的IP地址就能唯一的确定一个TCP连接。

  • 序号: 占 4 字节,TCP 连接中传送的数据流中的每一个字节都编上一个序号.序号字段的值则指的是本报文段所发送的数据的第一个字节的序号。Sequence Number:用来标识从TCP发端向TCP收端发送的数据字节流,它表示在这个报文段中的的第一个数据字节在数据流中的序号;主要用来解决网络报乱序的问题;

  • 确认号:占 4 字节,是期望收到对方的下一个报文段的数据的第一个字节的序号。Acknowledgment Number:32位确认序列号包含发送确认的一端所期望收到的下一个序号,因此,确认序号应当是上次已成功收到数据字节序号加1。不过,只有当标志位中的ACK标志(下面介绍)为1时该确认序列号的字段才有效。主要用来解决不丢包的问题。

  • 数据偏移(首部长度): 占 4 位,它指出 TCP 头部实际长度。Offset:给出首部中32 bit字的数目,需要这个值是因为任选字段的长度是可变的。这个字段占4bit(最多能表示15个32bit的的字,即4*15=60个字节的首部长度),因此TCP最多有60字节的首部。然而,没有任选字段,正常的长度是20字节。

    • 在 TCP 协议中,TCP 头部的长度是可变的,最小长度为 20 个字节,最大长度为 60 个字节。这是因为 TCP 头部中有一些可选字段,如 TCP 选项、窗口缩放因子等,这些字段的长度是可变的,因此 TCP 头部的长度也会随之变化。TCP 头部长度是通过 TCP 头部中的 数据偏移(首部长度)字段来指定的,它表示 TCP 头部的长度以 32 位字为单位计算的值。因此,TCP 头部长度实际上是 数据偏移(首部长度)字段值乘以 4。TCP Flags:TCP首部中有6个标志比特,它们中的多个可同时被设置为1,主要是用于操控TCP的状态机的,依次为URGACKPSHRSTSYNFIN。每个标志位的意思如下:
  • 状态位,占6比特:

    • URG:此标志表示TCP包的紧急指针域(后面马上就要说到)有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据。
    • ACK:该位为 1 时,「确认号」的字段变为有效,否则无效。此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0; TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1。
    • PSH:这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队。
    • RST:该位为 1 时,表示 TCP 连接中出现异常必须强制断开连接,然后重新建立新链接。这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包。
    • SYN:该位为 1 时,表示希望建立连接,并在其「序号」的字段进行序列号初始值的设定。
      表示同步序号,用来建立连接。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1,ACK=0;连接被响应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送一个只有SYN的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求一个连接严格的进行TCP的三次握手。
    • FIN:该位为 1 时,表示数据发送传输完毕,希望断开连接。表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。
  • 窗口:占2字节,用于流量控制,通信双方各声明一个窗口,标识自己当前的处理能力。控制报文别发太快,也别发太慢。 16位2字节,用于表示滑动窗口大小,窗口大小最大为65535(2^16-1)字节。

    接收方的流量控制手段,窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接收的字节。告诉发送端,接收端目前允许发送端数据量。大小两字节65535,在客户端与服务端 TCP 都允许的情况下,选项中可存在窗口扩展选项。 示例中:窗口大小65535,代表告诉发送方,从这个下一包0的序号开始,接收方只能接受65535个字节长度了(当然这里还没有算上扩展选项,稍后再讲)。

  • 检验和: 占 2 字节,校验数据是否完整未更改。 16位2字节,检验和覆盖了整个的 TCP 报文段: TCP 首部和 TCP 数据。这是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。和 UDP 用户数据报一样,在计算检验和时,要在 TCP 报文段的前面加上12字节的伪首部。伪首部的格式和 UDP 用户数据报的伪首部一样。但应把伪首部第4个字段中的17改为6(TCP的协议号是6);把第5字段中的UDP中的长度改为TCP长度。接收方收到此报文段后,仍要加上这个伪首部来计算检验和。若使用TPv6,则相应的伪首部也要改变。

    校验和错误的分组丢弃(因为源IP地址、源端口号或者协议字段可能被破坏)。

  • 紧急指针:16位2字节,在紧急 URG 标志执1的时候有效,代表一个偏移量,和序号字段值相加,代表紧急数据最后一个字节的序号。

  • 选项:长度可变,最长可达40字节。当没有使用"选项"时,TCP 的首部长度是20字节。其最大长度可根据 TCP 首部长度进行推算。TCP 首部长度用4位数据偏移表示,单位是4字节,那么选项部分最长为:(2^4-1)*4-20=40字节。TCP 协议最初只规定了一种选项,即最长报文段长度(数据字段加上TCP首部),又称为 MSS。MSS 告诉对方 TCP "我的缓存所能接收的报文段的数据字段的最大长度是 MSS 个字节"。

  • 填充: 为了使整个首部长度是 4 字节的整数倍。选项长度是指不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的0,以保证TCP头部是32的整数倍。

8.1TCP报文字段说明表格展示

有同学喜欢表格展示,宏哥也提供出来啦!

|-----------------------|--------|------------------------------------------------------------------------------------------------|
| 字段 | 长度 | 含义 |
| Source Port | 16比特 | 源端口,标识哪个应用程序发送。 |
| Destination Port | 16比特 | 目的端口,标识哪个应用程序接收。 |
| Sequence Number | 32比特 | 序号字段。TCP链接中传输的数据流中每个字节都编上一个序号。序号字段的值指的是本报文段所发送的数据的第一个字节的序号。 |
| Acknowledgment Number | 32比特 | 确认号,是期望收到对方的下一个报文段的数据的第1个字节的序号,即上次已成功接收到的数据字节序号加1。只有ACK标识为1,此字段有效。 |
| Data Offset | 4比特 | 数据偏移,即首部长度,指出TCP报文段的数据起始处距离TCP报文段的起始处有多远,以32比特(4字节)为计算单位。最多有60字节的首部,若无选项字段,正常为20字节。 |
| Reserved | 6比特 | 保留,必须填0。 |
| URG | 1比特 | 紧急指针有效标识。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。 |
| ACK | 1比特 | 确认序号有效标识。只有当ACK=1时确认号字段才有效。当ACK=0时,确认号无效。 |
| PSH | 1比特 | 标识接收方应该尽快将这个报文段交给应用层。接收到PSH = 1的TCP报文段,应尽快的交付接收应用进程,而不再等待整个缓存都填满了后再向上交付。 |
| RST | 1比特 | 重建连接标识。当RST=1时,表明TCP连接中出现严重错误(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立连接。 |
| SYN | 1比特 | 同步序号标识,用来发起一个连接。SYN=1表示这是一个连接请求或连接接受请求。 |
| FIN | 1比特 | 发端完成发送任务标识。用来释放一个连接。FIN=1表明此报文段的发送端的数据已经发送完毕,并要求释放连接。 |
| Window | 16比特 | 窗口:TCP的流量控制,窗口起始于确认序号字段指明的值,这个值是接收端正期望接收的字节数。窗口最大为65535字节。 |
| Checksum | 16比特 | 校验字段,包括TCP首部和TCP数据,是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。 |
| Urgent Pointer | 16比特 | 紧急指针,只有当URG标志置1时紧急指针才有效。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。紧急指针指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面)。 |
| Options | 可变 | 选项字段。TCP协议最初只规定了一种选项,即最长报文段长度(数据字段加上TCP首部),又称为MSS。MSS告诉对方TCP"我的缓存所能接收的报文段的数据字段的最大长度是MSS个字节"。 |
| Padding | 可变 | 填充字段,用来补位,使整个首部长度是4字节的整数倍。 |
| data | 可变 | TCP负载。 |

9.小结

今天主要详细地介绍了一下TCP包的理论知识,基本上都是文字,看起来比较晦涩难懂。下一篇宏哥打算讲解和分享一下:TCP的三次握手和四次挥手以及WireShark的实践。好了,今天时间也不早了,宏哥就讲解和分享到这里,感谢您耐心的阅读,希望对您有所帮助。