tcp三次握手和四次断开以及tcpdump的基本使用

2024-04-18 09:44

本文主要是介绍tcp三次握手和四次断开以及tcpdump的基本使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

最近工作中会发现有超时的问题,还有就是在面试的时候很多都要求深入理解TCP/IP协议。突然感觉TCP/IP协议是一个既熟悉,又陌生的技术。又想到上大学的时候,老师说过
网络的圣经:“TCP/IP详解” 卷一 卷二 卷三,三本书。所以这次写一篇文档,好好学习一下。以下文档是根据TCP/IP详解 卷一和网络文章综合所得

一、tcpdump准备工作

1.操作系统版本

[root@web-server ~]# cat /etc/redhat-release 
CentOS Linux release 7.6.1810 (Core)

2.tcpdump安装

yum -y install tcpdump

3.tcpdump版本

[root@web-server ~]# tcpdump --version
tcpdump version 4.9.2
libpcap version 1.5.3
OpenSSL 1.0.2k-fips  26 Jan 2017

二、tcpdump用法

1. 网卡参数 -i

指定网卡的选项是必须的。我看网上很多资料不用指定网卡,可以直接过滤,不知道是不是tcpdump版本过低的问题
可以使用tcpdump -D 打印出可以监控的网络接口有哪些

1.1 指定固定网卡

指定接收ens32网卡的所有收发数据包,

 tcpdump -i ens32 -c 10

1.2 指定所有网卡

tcpdump -i any -c 10

2.指定协议

查看icmp协议的收发数据包.可以通过客户端ping服务器,来查看数据包的情况

tcpdump -i ens32 icmp
tcpdump -i ens32 arp
tcpdump -i ens32 tcp

3.指定端口 port

要想抓取应用层的访问数据包,就应该通过端口来抓取了。
服务端安装nginx,进行测试

tcpdump -i ens32  port  80

3.1 指定目标端口

tcpdump -i ens32  dst port  80

3.2 区别

如果不指定目标端口,会显示通过80端口上所有接收和发送的数据包
如果指定目标端口,只会显示访问80的数据包,通过80发送出去的数据包不会显示

4.过滤主机 host

4.1 过滤源主机IP地址

tcpdump   -i ens32  src host  192.168.1.3

5.组合使用

以上条件组合起来一起使用必须使用and进行连接.
例子1:获取源主机为1.3 在80端口上所有收发的数据包

tcpdump   -i ens32  src host  192.168.1.3 and port 80

例子2:查看正在Ping服务器(1.102)的所有主机

tcpdump   -i ens32  icmp and dst host 192.168.1.102

例子3:查看某台主机是否在ping服务器(1.20)

tcpdump  -i ens32 icmp and dst 192.168.1.102 and src 192.168.1.103

6.tcpdump数据格式

格式如下:

22:57:09.763679 IP 192.168.1.102.80 > 192.168.1.103.57296: Flags [S.], seq 1928661013, ack 1195573118, win 28960, options [mss 1460,sackOK,TS val 8656013 ecr 8681178,nop,wscale 7], length 0
格式:
1. 22:57:09.763679 :数据请求的时间
2. IP: 表示网络协议
3. 192.168.1.102.80: 源地址IP和端口号
4. > : 数据走向,也就说谁发给谁的数据包
5. 192.168.1.103.57296:目标IP地址和端口号 
6. Flags [P.]: 标识位其它: seq号 ack号 win窗口  数据长度length

7、其他参数

7.1 -v和-vv

显示更详细的信息

7.2 -nn

以数字的形式显示端口号和IP地址

7.3 -P

查看进出口数据包。-P (in|out)

tcpdump  -i ens32  -P out  dst 192.168.1.103 -nn

7.4 -w

将捕获到的数据包保存到文件当中,文件后缀需要使用.pcap。 然后方便使用wireshark软件进行查看

7.5 -S

将TCP的序列号,以绝对值的形式输出。如果不使用-S参数,在抓包过程中ack的值会这样显示:ack=1,这样不便于观察。

7.6 -t

不显示时间戳

三、TCP协议

1.简介

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

1.1 面向连接

面向连接指的是:客户端和服务端要交互数组,必须要先建立连接。

1.2 可靠性

TCP协议的可靠性主要靠以下几个方面:
(1)应用数据会被TCP分割成 TCP认为最合适的数据块
(2)TCP发出一个数据段后,会启动一个定时器,等待目的端确认是否收到这个数据段,如果不能及时收到一个确认。将重新发送这个数据段
(3)目的端收到数据后,发送一个确认,这个确认不会立即发送,通常会推迟几分之一秒
(4)TCP协议会重新对数据段进行排序
(5)TCP会丢弃"重复"、"首部和数据的校验和有差错"的数据段

2.TCP报文

在这里插入图片描述

2.1 源端口和目标端口

源端口:表示是哪个进程发来的数据包
目标端口:表示这个数据包要发送给哪个进程

2.2 序号和确认号

(1)序号:指定了当前数据分片中分配给第一字节数据的序列号。在TCP传输流中每一个字节为一个序号。如果TCP报文中flags标志位为SYN,该序列号表示初始化序列号(ISN),此时第一个数据应该是从序列号ISN+1开始。

(2)确认号:表示TCP发送者期望接受下一个数据分片的序列号。该序号在TCP分片中Flags标志位为ACK时生效。
作用1:确认对端发来的包收到了。
作用2:期望对端开始传输数据时候,序列号从这个值开始
此值一般是在对端的序列号上加1

3.标志位

标志位含义备注
SYN连接请求或者接受连接请求在tcpdump中的表现形式为: 【S】
FIN连接结束,断开连接在tcpdump中的表现形式为: 【F】
RST重置连接在tcpdump中的表现形式为: 【R】
ACK确认标记位【.】代表ACK的确认包 或者URG标志位。其它的标志位均为0.一般情况下就ACK包
PSH催促标志位在tcpdump中的表现形式为: 【P】 推送数据
URG紧急标志位【.】代表ACK的确认包 或者URG标志位.其它的标志位均为0

注意:

1.PSH标志位:提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间。如果为1,则表示对方应当立即把数据提交给上层应用,而不是缓存起来,如果应用程序不将接收到的数据读走,就会一直停留在TCP接收缓冲区中2.RST标志位:如果收到一个RST=1的报文,说明与主机的连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。或者说明上次发送给主机的数据有问题,主机拒绝响应,带RST标志的TCP报文段称为复位报文段即连接重置

四、TCP连接的建立

1.简介

TCP的连接也就是"三次握手"的过程。
所谓三次握手就是指:建立一个 TCP 连接时需要客户端和服务器端总共发送三个包来确认连接的建立

2.三次握手的过程

在这里插入图片描述

3.抓包实例

3.1 抓包命令

在server启动nginx,开始进行抓包,命令如下

tcpdump -i any -nn -S  port 80

3.2 抓包结果

使用telnet进行连接nginx的80端口

telnet 192.168.1.16 80

查看抓包内容,结果如下:

01:16:08.055233 IP 192.168.1.1.57853 > 192.168.1.16.80: Flags [S], seq 1599595106, win 64240, 
01:16:08.055284 IP 192.168.1.16.80 > 192.168.1.1.57853: Flags [S.], seq 4257773931, ack 1599595107, win 29200, 
01:16:08.055804 IP 192.168.1.1.57853 > 192.168.1.16.80: Flags [.], ack 4257773932, win 4106, length 0

4.结果分析

4.1 第一次握手

客户端发送给服务器端

192.168.1.1.57853 > 192.168.1.16.80[S]: 发送SYN 标志位位1的 数据包,
seq: 初始的随机序列号值为1599595106总结: SYN=1,seq=1599595106

4.2 第二次握手

服务端回应客户端

192.168.1.16.80 > 192.168.1.1.57853[S.]: SYN和ACK标志位都为1,
ack: 确认序号为  1599595107,在客户端发来的序号之上 + 1
seq: 产生和客户端建立连接的初始化序列号4257773931总结:
SYN=1,seq=4257773931
ACK=1,ack=1599595107

4.3 第三次握手

客户端确认

192.168.1.1.57853 > 192.168.1.16.80[.] ACK标志位为1
ack:确认号4257773932总结:
ACK=1,ack=4257773932

就第三次握手的情况来看,第三的包中并没有携带seq 序列号值。这是因为默认没有显示,可以使用-vv参数来查看
但是在windows中使用wireshark抓包,可以看到seq这个序列号。

5.状态验证

5.1 查看SYN_SENT

在服务端启动防火墙,客户端就无法连接nginx.
查看服务器抓包情况,可以看出客户端一直在发送建立连接的包

18:13:31.336551 IP 192.168.1.1.61419 > 192.168.1.16.80: Flags [S], seq 1643209252, win 64240
18:13:31.341627 IP 192.168.1.1.61420 > 192.168.1.16.80: Flags [S], seq 142056919, win 64240
18:13:31.587559 IP 192.168.1.1.61422 > 192.168.1.16.80: Flags [S], seq 3305175899, win 64240
18:13:34.336935 IP 192.168.1.1.61419 > 192.168.1.16.80: Flags [S], seq 1643209252, win 64240
18:13:34.344128 IP 192.168.1.1.61420 > 192.168.1.16.80: Flags [S], seq 142056919, win 64240

查看客户端状态,处于SYN_SENT状态。这里的连接数量不重要,主要是看状态

C:\Users\pangbb>netstat -an |findstr /i 1.16|findstr /i 80TCP    192.168.1.1:61419      192.168.1.16:80        SYN_SENTTCP    192.168.1.1:61420      192.168.1.16:80        SYN_SENTTCP    192.168.1.1:61422      192.168.1.16:80        SYN_SENT

5.2 查看SYN_RECV

环境:

server: nc -l 16868在服务端的抓包命令:
tcpdump -i any -nn -S port 16868

此时开启客户端(linux)的设置iptables策略。1.16为服务端地址。含义就是不接受服务端返回

iptables -A INPUT -s 192.168.1.16 -j DROP

然后发起连接

nc -v 192.168.1.16 16868

查看服务端状态

[root@node1 ~]# netstat -antp |grep 16868
tcp        0      0 0.0.0.0:16868           0.0.0.0:*               LISTEN      7308/nc             
tcp        0      0 192.168.1.16:16868      192.168.1.18:34786      SYN_RECV    -                   
tcp6       0      0 :::16868                :::*                    LISTEN      7308/nc

五、TCP连接的断开

1.简介

在TCP连接中的断开 常被称为"四次断开"或者"四次挥手"
之所以断开需要四次:
这是因为TCP的"半关闭"造成的.TCP是全双工的,因此每个方向必须单独地进行关闭

2.四次断开过程

2.1 过程图

这里的过程图,没有过多些回复包的seq序列号。这里主要是看状态的转换

在这里插入图片描述

2.2 端口状态

(1)主动断开方:

FIN_WAIT1
FIN_WAIT2
TIME_WAIT 

(2)被动断开方

CLOSE_WAIT
LAST_ACK

3.nc实现标准4次断开

3.1 启动抓包命令

tcpdump -i any -S -nn port  16868

3.2 启动nc

在server上使用以下命令启动16868端口

nc -l 16868

3.3 客户端连接

在客户端cmd中使用telnet连接server的16868端口

telnet 192.168.1.16  16868

nc命令不会主动断开连接。不手动断开是不会断开连接的。

3.4 断开连接

使用telnet连接nc端口后,可以在客户端输入点数据。也可以不输入数据。
然后在"服务端"端开始断开连接,注意:一定要在服务端主动断开。也就是停止nc命令。

3.5 查看抓包结果

这里展现了标准的tcp 4次断开结果

# 服务端主动断开nc命令,服务端向客户端发起断开请求 第一次
192.168.1.16.16868 > 192.168.1.1.50907: Flags [F.], seq 2801815419, ack 3112729795, win 229, length 0# 客户端收到服务端断开连接的请求,回复ACK 进行确认。 第二次
192.168.1.1.50907 > 192.168.1.16.16868: Flags [.], ack 2801815420, win 4106, length 0# 客户端开始向服务端发起断开连接请求, 第三次
192.168.1.1.50907 > 192.168.1.16.16868: Flags [F.], seq 3112729795, ack 2801815420, win 4106, length 0# 服务端确认客户端的请求。第四次
192.168.1.16.16868 > 192.168.1.1.50907: Flags [.], ack 3112729796, win 229, length 0

4.nginx断开实例

3.1 启动nginx

nginx

3.2 开始抓包

tcpdump -i any -nn -S port 80

使用浏览器访问nginx,得到以下抓包数据

# nginx主动发起 第一次断开连接的请求
01:50:13.124555 IP 192.168.1.16.80 > 192.168.1.1.55320: Flags [F.], seq 3869309450, ack 202349151, win 254, length 0
01:50:13.124900 IP 192.168.1.1.55320 > 192.168.1.16.80: Flags [.], ack 3869309451, win 4102, length 0# 后续的包不通场景有些不同,这里只是想表达 nginx会主动发断开的FIN包

3.3 状态转换

在建立完连接之后,nginx在 “keepalive_timeout” 时间内,客户端没有传输数据,nginx就会自动断开连接。发送FIN包,进行断开.
(1)当nginx主动发起FIN断开连接后,服务端将进入 “FIN_WAIT2” 状态
(2)此时客户端进入"CLOSE_WAIT"
(3)当客户端端像nginx发起FIN后,nginx的连接进入"TIME_WAIT"

5.断开得状态复现

1、主动关闭方发送FIN,此时主动关闭方状态为:FIN_WAIT_1
2、被动关闭方收到后,回复ack,此时被动关闭方状态为:CLOSE_WAIT
3、主动关闭方收到ack后,状态为FIN_WAIT_2
4、被动关闭方发送FIN,此时状态为LAST_ACK
5、主动关闭方收到后,回复ack,此时状态为TIME_WAIT 。
6、被动关闭方收到ack后,状态为CLOSED

为了方便看到TCP断开状态得转换和查看。server和client都使用"nc"进行实现
server端使用linux 192.168.1.16 使用nc
client端使用linux 192.168.1.18 也使用nc

5.1.FIN_WAIT_1

5.1.1 启动server
nc -l 16868#开始启动抓包
tcpdump -nn -S -i any port 16868
5.1.2 client开始连接
nc -v 192.168.1.16 16868
5.1.3 设置客户端防火墙策略

此策略得目的就是不接受服务端发来得FIN 断开请求包

ptables -A INPUT -s 192.168.1.16 -j DROP
5.1.4 断开服务端

直接ctrl + c 断开即可

5.1.4 查看服务端状态
[root@node1 ~]# netstat -antp |grep 16868
tcp        0      1 192.168.1.16:16868      192.168.1.18:34826      FIN_WAIT1   -

5.2 FIN_WAIT_2

先还原正常建立连接得正常状态. 清除所有防火墙策略

5.2.1 启动server
nc -l 16868#开始启动抓包
tcpdump -nn -S -i any port 16868
5.2.1 client开始连接
nc -v 192.168.1.16 16868
5.2.3 断开服务端

直接ctrl + c 断开即可。此时 client得nc 不会自动断开。必须手动断开才可以

5.2.4 查看抓包结果

这里发现客户端已经回复了ACK得的确认包

18:43:08.639049 IP 192.168.1.16.16868 > 192.168.1.18.34828: Flags [F.], seq 1714549503, ack 38581695, win 227, options [nop,nop,TS val 77246674 ecr 77160729], length 0
18:43:08.641121 IP 192.168.1.18.34828 > 192.168.1.16.16868: Flags [.], ack 1714549504, win 229, options [nop,nop,TS val 77241592 ecr 77246674], length 0
5.2.5 查看服务端状态

此时服务端得连接状态已经变成了FIN_WAIT2

[root@node1 ~]# netstat -antp |grep 16868
tcp        0      0 192.168.1.16:16868      192.168.1.18:34836      FIN_WAIT2   - 
5.2.6 查看客户端状态

此时发现客户端已经进入到CLOSE_WAIT状态

[root@node4 ~]# netstat -antp |grep 16868
tcp        0      0 192.168.1.18:34836      192.168.1.16:16868      CLOSE_WAIT  4308/nc 

5.3 TIME_WAIT

TIME_WAIT状态 是为了等待足够的时间以确保对端能够收到自己发送的断开确认包。

5.3.1 启动server
nc -l 16868#开始启动抓包
tcpdump -nn -S -i any port 16868
5.3.2 client开始连接
nc -v 192.168.1.16 16868
5.3.3 断开服务端

查看服务端已经处于FIN_WAIT2状态

5.3.4 断开客户端

此时发现服务端已经变成了TIMW_WAIT状态了

[root@node1 ~]# netstat -antp |grep -i 16868
tcp        0      0 192.168.1.16:16868      192.168.1.18:34836      TIME_WAIT   - 

这篇关于tcp三次握手和四次断开以及tcpdump的基本使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

基本知识点

1、c++的输入加上ios::sync_with_stdio(false);  等价于 c的输入,读取速度会加快(但是在字符串的题里面和容易出现问题) 2、lower_bound()和upper_bound() iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。 iterator upper_bou

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联