TCP连接过程及报文解析

Wesley13
• 阅读 997

可能大家都听过TCP建立连接时需要经历三次握手和四次挥手的。

那么具体的握手挥手的过程是怎么样的呢?

这篇文章就通过WireShark抓包来了解TCP连接建立和断开的过程。

实验方法:

写一段简单的代码 代码客户端和服务端,分别部署,让客户端主动像服务器发起连接,随后断开。让WireShark抓股这个过程中产生了哪些包,并对其分析。

(注:WireShark默认不支持LoopBack,需要将客户端和服务端分开部署,或是配置WireShark)。

首先,我们先来看一下连接建立和断开的过程中,产生了哪几个包。

TCP连接过程及报文解析

从上图我们可以看到,正好是七个包,符合我们三次握手四次挥手的过程。

分析其过程,WireShark已经为我们解析了每个TCP包的标志位(之后会详细解释,主要用来区分每个包的用途)。

TCP建立连接:

1).客户端向服务器发起建立连接请求(SYN)

2).服务端收到后,像客户端回复一个建立连接请求的响应(SYN,ACK)

3).客户端收到后,继续向服务端发送一个响应(ACK)

三次握手完成,正式建立连接。

TCP断开连接

1).断开发起方向另一方发送断开连接请求(FIN,ACK)

2).另一方收到后,回复一个响应(ACK)

3).再由另一方主动发送一个断开连接请求(FIN,ACK)

4).断开发起方收到后,回复一个响应(ACK)

四次挥手完成,断开SOCKET连接。

我们通过图片来加深一下印象:

TCP连接过程及报文解析

了解完过程,再让我们通过分析第一个包的内容,初步了解下TCP报文结构:

我们可以看到整个消息帧是66个字节:

TCP连接过程及报文解析

1).该帧是一个以太网消息帧:分为首部和数据两个部分。

首部前六个字节(30 9c 23 bc 9d 80)表示目的地MAC地址

后六个字节(30 9c 23 1c 0f 74)表示源MAC地址

我们可以看到当数据在链路层中传输的时候,是由MAC地址标识定位的。

之后两个字节(08 00)表示上层协议类型(这里的0x 08 00表示的就是IP协议)

剩余的52(66 - 6 - 6 - 2)个字节为数据部分,来承载上层协议(本例中为IP协议)的消息。

2).从第十三个字节开始为IP协议的包,

IP协议同样分为首部和数据两部分内容。

首部由20字节固定长度+选项两部分构成。

先看来固定长度的内容

第一个字节拆成两部分解析,前四位表示版本号,后四位表示首部的长度:0x45,4 表示版本4,也就是我们常说的IPv4,5表示5个单位(最小单位为4字节),因此是5 * 4 = 20个字节(正好为固定长的,因此这个包中没有选项)。

第二个字节表示服务类型:00

接下来的两个字节表示消息总字节数:0x 00 34 = 52(字节) 

接下来的两个字节(0x 4e da)表示标识符(Identification),表示唯一的一个IP消息包,同一包的IP分片消息此ID相同,用来对IP消息重组

接下来的两个字节(0x 40 00)表示标志位(Flags),前四位中的第一位为预留,后三位为标识位,又来表示是否有分片,是否是最后一片,后13位为片偏移,具体可以了解IP分片

接下来的一个字节是TTL(Time To Live):表示最大生存时间,通常用来表示最大穿越路由层数,没穿过一个路由,TTL变回-1,到0时这个IP包就会被丢弃,此处是0x80 = 128

接下来的一个字节表示上层协议,此处是0x06,表示上层是TCP协议

接下来的两个字节是校验和(0x00 00)

接下来的四个字节(0x c0 a8 01 9c)是源IP地址,尝试解析一下 c0 = 12 * 16 + 0 =192 , 依次解析得到(192.168.1.156)

接下来的四个字节(0x c0 a8 01 66)是目的IP地址 

到此一共1 +1 + 2 + 2 + 2  + 1 + 1 + 2 + 4 + 4 = 20个字节。此例中没有选项,因此剩下的32个字节的数据,用来表示上层协议(TCP)

3).从f8开始就是我们的TCP协议。

TCP协议也由首部和数据两部分组成,首部和IP协议类似,由20字节固定长度和可选部分组成,数据部分主要是包含了上层协议的内容(如HTTP协议等)。

TCP协议的头两个字节(0x f8 eb)表示源端口

后两个字节(0x 1a 0a)表示目的端口

接下来的四个字节表示序列号seq(0x 43 03 7a c8)

接下来的四个字节表示应答号ack(0x 00 00 00 00)

接下来的两个字节(0x 8002)表示首部长度及标志位:首先, 前四位表示首部长度(8,单位同样是4字节,因此表示首部为32字节);后12位中的前三位为预留,后九位为标志位。

了解一下后12位,其中Reserved表示三位。

Reserved

NS

CWR

ECE

URG

ACK

PSH

RST

SYN

FIN

**NS(NONCE):**有了解的朋友可以补充一下

CWR(Congestion Window Reduce**)**:拥塞窗口减少标志被发送主机设置,用来表明它接收到了设置ECE标志的TCP包,发送端通过降低发送窗口的大小来降低发送速率

**ECE(ECN Echo)**:ECN响应标志被用来在TCP3次握手时表明一个TCP端是具备ECN功能的,并且表明接收到的TCP包的IP头部的ECN被设置为11。更多信息请参考RFC793。

**URG(Urgent)**:该标志位置位表示紧急(The urgent pointer) 标志有效。该标志位目前已经很少使用参考后面流量控制和窗口管理部分的介绍。

**ACK(Acknowledgment)**:取值1代表Acknowledgment Number字段有效,这是一个确认的TCP包,取值0则不是确认包。

**PSH(Push)**:该标志置位时,一般是表示发送端缓存中已经没有待发送的数据,接收端不将该数据进行队列处理,而是尽可能快将数据转由应用处理。在处理 telnet 或 rlogin 等交互模式的连接时,该标志总是置位的。

**RST(Reset)**:用于复位相应的TCP连接。通常在发生异常或者错误的时候会触发复位TCP连接。

SYN(Synchronize**)**:同步序列编号(Synchronize Sequence Numbers)有效。该标志仅在三次握手建立TCP连接时有效。它提示TCP连接的服务端检查序列编号,该序列编号为TCP连接初始端(一般是客户端)的初始序列编号。在这里,可以把TCP序列编号看作是一个范围从0到4,294,967,295的32位计数器。通过TCP连接交换的数据中每一个字节都经过序列编号。在TCP报头中的序列编号栏包括了TCP分段中第一个字节的序列编号。类似的后续文章介绍中当这个SYN标志位有效的时候我们称呼这个包为SYN包。

**FIN(Finish)**:带有该标志置位的数据包用来结束一个TCP会话,但对应端口仍处于开放状态,准备接收后续数据。当FIN标志有效的时候我们称呼这个包为FIN包。

 回到TCP报文中来:

接下来的两个字节(0x 20 00)表示窗口大小(Window Size),表示TCP还可以接受的空间大小。

接下来的两个字节(0x 84 79)表示校验和(Checksum),用来校验数据

接下来的两个字节(0x 00 00)表示优先级指针(Urgent Pointer),只有当标志位中的URG设为1时才有效,

到此,TCP首部的固定长的20个字节已经解析完毕。

我们看到首部还剩余12个字节,这个TCP首部中的选项,选项是可选的,以四字节为单位扩展,用来记录时间戳等内容。

本包抓取的是TCP第一次握手的内容,因此TCP报文中没有数据。

说了这么多,可能还是会有点乱,对上述内容整理一张图片帮助大家加深理解:

TCP连接过程及报文解析

另外,上述解析的过程可以在WireShark中很清楚的看到,建议大家自己也抓取一个包,加深理解。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Easter79 Easter79
3年前
tcp编程、socket编程、redis
tcp编程(需要建立连接,三次握手,四次挥手,然后发送信息流,数据包是有序的)udp编程(知道IP、端口直接发送数据,数据包可能是无序的)1、客户端和服务器客!(http
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
TCP三次握手和四次挥手
建立TCP连接:三次握手TCP在传输数据之前,首先需要建立好TCP连接,后续所有数据都基于这个已建立的连接来传输,建立TCP连接的过程通常被描述为三次握手屏幕快照2020072716.44.59!TCP三次握手和四次挥手(https://s4.51cto.com/images/blog/202007/27/e095cdb6ee5e99
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
TCP是如何实现三次握手的?
什么是三次握手1.TCP是网络传输层的协议,提供面向连接的可靠的字节流服务,要通信得先建立连接2.所谓三次握手就是指,建立一个TCP连接时,需要CLient与Server发送三个包,确认连接的建立3.这一过程由Client执行connect触发简单描述下三次握手的具体过程第一
Wesley13 Wesley13
3年前
34.TCP取样器
阅读文本大概需要3分钟。1、TCP取样器的作用   TCP取样器作用就是通过TCP/IP协议来连接服务器,然后发送数据和接收数据。2、TCP取样器详解!(https://oscimg.oschina.net/oscnet/32a9b19ba1db00f321d22a0f33bcfb68a0d.png)TCPClien
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这