当前位置: 首页 > news >正文

Golang案例开发之gopacket抓包三次握手四次分手(3)

文章目录

  • 前言
  • 一、理论知识
    • 三次握手
    • 四次分手
  • 二、代码实践
    • 1.模拟客户端和服务器端
    • 2.三次握手代码
    • 3.四次分手代码
    • 验证代码
    • 完整代码
  • 总结


前言

TCP通讯的三次握手和四次分手,有很多文章都在介绍了,当我们了解了gopacket这个工具的时候,我们当然是用代码实践一下,我们的理论。本节内容就是好的实践。
先看下我们本次实践的效果:
在这里插入图片描述


一、理论知识

三次握手

三从握手状态变迁
在这里插入图片描述

  1. 第一次握手:客户端向服务器发送一个SYN报文段,报文段的首部中的标志位SYN置为1,另外还会指明自己的初始化序号seq=x,此时客户端处于SYN_SENT状态。
  2. 第二次握手:服务器收到SYN的报文段后,会以自己的SYN-ACK报文进行应答。该应答报文的首部有三个重要信息:首先SYN被置为1;其次,确认号字段ack=x+1;最后服务器选择自己的初始序号seq=y。该报文段表明:“我收到了你发起建立连接的请求,该请求报文的初始序号是x(确认号ack=x+1就表明了我收到了初始序号seq=x的报文),我同意建立该连接,我的初始序号是y。”此时服务器处于SYN_RCVD状态。
  3. 第三次握手:客户端收到SYN-ACK报文后,会发送一个ACK报文段,该报文段中序号seq=x+1,确认号ack=y+1,表明我已经收到了你的确认。此时客户端处于ESTABLISHED状态。
    需要注意的是:第一次握手和第二次握手都只是消耗掉一个序号,但不能携带数据;第三次握手可以携带数据。

四次分手

在这里插入图片描述
初始时,客户端与服务器都处于ESTABLISHED状态,假如客户端发起断开连接的请求(服务器也可以发起)

  1. 第一次挥手:客户端发送一个FIN报文段,报文段中指定序号seq=u。此时客户端处于FIN_WAIT_1状态。
  2. 第二次挥手:服务器收到FIN报文后,立即发送一个ACK报文段,确认号为ack=u+1,序号设为seq=v。表明已经收到了客户端的报文。此时服务器处于CLOSE_WAIT状态。
    在第二次挥手和第三次挥手之间的时间段内,由于只是半关闭的状态,数据还是可以从服务器传送到客户端的。
  3. 第三次挥手:如果数据传送完毕,服务器也想断开连接,那么就发送一个FIN报文,并重新指定一个序号seq=w,确认号还是ack=u+1,表明可以断开连接。
  4. 第四次挥手:客户端收到报文后,一样发出一个ACK报文段做出应答,上一次客户端发送的报文段序号为u,那么这次序号就是seq=u+1,确认号为ack=w+1。此时客户端处于TIME_WAIT状态,需要经过一段时间确保服务器收到自己的应答报文后,才会进入CLOSED状态。

二、代码实践

1.模拟客户端和服务器端

我们准备了两台Linux虚拟机,分别是:
192.168.37.90 Client
192.168.37.100 Server
服务器端,我们可以启动一个Python的http服务来模拟。一般的Linux服务只要有Python2都可以运行:

python -m SimpleHTTPServer 8000

输入命令后,启动了一个监听8000端口的HttpServer服务。

客户端,我们直接用curl命令或者telnet

curl http://192.168.37.100:8000
或者
telnet 192.168.37.100 8000

下图,可以看到刚才的curl命令已经成功请求了。
在这里插入图片描述
客户端和服务器端都准备好了,现在开始开发我们的监听代码,我们的目标是获取到三次握手和四次分手的网络包。

2.三次握手代码

上一节,我们已经完成了网络包分层的代码,既然是要抓TCP的包,我们这次就关注tcpLayer := packet.Layer(layers.LayerTypeTCP) 这部分。
在这里插入图片描述
经过断言后,tcp 变量里面就可以获取到TCP层的所有信息。
我们先看三次握手:
第一次握手,SYN标志位为True,ACK标志位为False
第二次握手,SYN标志位和ACK标志位都为True
第三次握手,SYN标志位为False,ACK标志位为True,同时AckNum确认值是第二次握手SeqNum+1
结合情况,我们可以这样获取:
声明变量SecondSeqNum ,记录第二次握手的序列号。
var SecondSeqNum uint32

	tcpLayer := packet.Layer(layers.LayerTypeTCP)if tcpLayer != nil {tcp, _ := tcpLayer.(*layers.TCP)// TCP layer variables:// S

相关文章:

  • C语言UNIX域套接字CS模型
  • 全局UI方法-弹窗六-自定义弹窗
  • Flask 与小程序 的图片数据交互 过程及探讨研究学习
  • 如何在群晖NAS搭建bitwarden密码管理软件并实现无公网IP远程访问
  • Install Docker
  • 【机器学习】代价函数
  • #Linux(make工具和makefile文件以及makefile语法)
  • spark: 从pulsar中读取数据
  • tcpdump 抓包
  • 基于STELLA系统动态模拟技术及在农业、生态及环境科学中的应用教程
  • WINDOWS设置代理链chain
  • 一文整合工厂模式、模板模式、策略模式
  • 什么是通配符SSL证书?
  • Webgl学习系列-认识Webgl
  • 一、TLE9471 - SBC Mode切换 + VCC2 开关
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • Android优雅地处理按钮重复点击
  • Android组件 - 收藏集 - 掘金
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • GitUp, 你不可错过的秀外慧中的git工具
  • If…else
  • java8 Stream Pipelines 浅析
  • JavaScript 基础知识 - 入门篇(一)
  • Java基本数据类型之Number
  • JDK 6和JDK 7中的substring()方法
  • Js基础——数据类型之Null和Undefined
  • leetcode98. Validate Binary Search Tree
  • vue-router 实现分析
  • 分享几个不错的工具
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 关于Flux,Vuex,Redux的思考
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 嵌入式文件系统
  • 入口文件开始,分析Vue源码实现
  • 入门到放弃node系列之Hello Word篇
  • 时间复杂度与空间复杂度分析
  • 算法之不定期更新(一)(2018-04-12)
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • #define、const、typedef的差别
  • (1)(1.13) SiK无线电高级配置(六)
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (附源码)springboot宠物医疗服务网站 毕业设计688413
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (十一)图像的罗伯特梯度锐化
  • (四)JPA - JQPL 实现增删改查
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • ./和../以及/和~之间的区别
  • .form文件_一篇文章学会文件上传
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .NET/C# 的字符串暂存池
  • .Net多线程总结