用 shell 脚本做 tcp 协议模拟

问题背景

公司有一套消息推送系统(简称GCM),由于人事变动接手了其中的客户端部分。看了一下文档,仅通讯协议部分有几页简单的说明,代码呢又多又乱,一时理不出一个头绪。由于消息是从后台推送到端的,所以使用了 tcp 长连接通道来保证消息的及时性,基于 http 的一堆分析工具(如 postman)完全没有用武之地,因此决定写个小工具来模拟 tcp 上的通讯协议,作为深入熟悉代码之前的热身。

问题的解决

一开始想用 c++ 来写这个工具,但是想到 socket 一连串经典的(socket / bind / connect / send / recv…)的繁琐调用我还是算了,之前用 shell 写过几个小工具很舒爽,但那都是借用 curl 命令来处理 http 协议,面对 tcp 协议 curl 肯定是无能为力了,因为命令执行完成后连接也就断开了,无法模拟长连接。那是不是就不能用 shell 写了呢?非也。

连接的建立与断开

我突然想到 shell 本身好像可以支持将 tcp 连接打开为文件:

bash;gutter:false; exec N <> /dev/tcp/host/port</p> <pre><code> 上面这段脚本就可以在句柄为 N 的文件上打开到 host 且端口为 port 的 tcp 连接了,并且可以进行双向读写。于是赶快在 msys2 中试了一下: </code></pre> <p>1 exec 3<>/dev/tcp/$gcm_host/$gcm_port 2 ret=$?</p> <p>3 echo "open tcp $ret" 4 if [ $ret != 0 ]; then 5 echo "connect to gcmserver failed" 6 exit 1 7 fi 8 9 echo "connect with server"</p> <pre><code> 这里脚本直接使用标准输入(0)、输出(1)、错误(2)之后的句柄 3 作为连接句柄,跑了一下,似乎什么也没有发生: ![用 shell 脚本做 tcp 协议模拟](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20230605/1707550-20201124134828692-1592037169.png) 好在 Windows 上有 procexp 工具,可以查看进程创建的所有 tcp 连接: ![用 shell 脚本做 tcp 协议模拟](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20230605/1707550-20201124135052804-866392507.png) 看起来这个连接确实建立成功了。当然你也可以用 windows 上的 netstat 命令查看: ;gutter:false;
C:\Users\yunh>netstat -no

活动连接

协议 本地地址 外部地址 状态 PID
TCP 10.2.56.38:1993 10.100.200.2:10003 ESTABLISHED 10320
TCP 10.2.56.38:2346 175.27.0.15:80 ESTABLISHED 14808
TCP 10.2.56.38:2474 121.51.139.161:8080 ESTABLISHED 15092
TCP 10.2.56.38:3147 10.2.56.13:7680 ESTABLISHED 8816
TCP 10.2.56.38:3576 47.97.243.182:80 ESTABLISHED 11292
TCP 10.2.56.38:3602 10.0.24.13:28888 ESTABLISHED 16224
TCP 10.2.56.38:3720 113.96.233.143:443 ESTABLISHED 15252
TCP 10.2.56.38:5006 10.2.61.20:7680 ESTABLISHED 8816
TCP 10.2.56.38:5022 10.2.25.16:7680 ESTABLISHED 8816
TCP 10.2.56.38:5303 49.232.126.211:443 ESTABLISHED 11292
TCP 10.2.56.38:6182 10.0.109.249:443 ESTABLISHED 16168
TCP 10.2.56.38:6183 10.0.109.249:443 ESTABLISHED 16168
TCP 10.2.56.38:6357 52.11.109.209:443 ESTABLISHED 11292
TCP 10.2.56.38:6697 40.90.189.152:443 ESTABLISHED 5268
TCP 10.2.56.38:7065 117.18.237.29:80 CLOSE_WAIT 4724
TCP 10.2.56.38:7100 220.170.53.122:443 TIME_WAIT 0
TCP 10.2.56.38:7113 220.181.174.166:443 TIME_WAIT 0
TCP 10.2.56.38:7117 180.163.150.166:443 ESTABLISHED 11292
TCP 10.2.56.38:7135 140.143.52.226:443 TIME_WAIT 0
TCP 10.2.56.38:7141 10.0.24.13:8888 CLOSE_WAIT 16224
TCP 10.2.56.38:7143 101.201.169.146:443 TIME_WAIT 0
TCP 10.2.56.38:7144 103.15.99.107:443 TIME_WAIT 0
TCP 10.2.56.38:7148 203.119.214.115:443 TIME_WAIT 0
TCP 10.2.56.38:7149 61.151.167.89:443 TIME_WAIT 0
TCP 10.2.56.38:7150 203.119.169.141:443 TIME_WAIT 0
TCP 10.2.56.38:7151 203.119.144.59:443 TIME_WAIT 0
TCP 10.2.56.38:7159 114.55.187.58:443 ESTABLISHED 11292
TCP 10.2.56.38:7160 42.121.254.191:443 TIME_WAIT 0
TCP 10.2.56.38:7162 118.178.109.187:443 TIME_WAIT 0
TCP 10.2.56.38:7165 47.110.223.99:443 TIME_WAIT 0
TCP 10.2.56.38:7166 116.62.93.118:443 TIME_WAIT 0
TCP 10.2.56.38:7195 123.150.76.171:80 CLOSE_WAIT 10772
TCP 10.2.56.38:6974 ################## ESTABLISHED 10984
TCP 10.2.56.38:7215 192.168.0.9:80 CLOSE_WAIT 4700
TCP 10.2.56.38:7218 10.2.100.217:7680 SYN_SENT 8816
TCP 10.2.56.38:7219 192.168.56.1:7680 SYN_SENT 8816
TCP 10.2.56.38:7680 10.2.102.27:53199 ESTABLISHED 8816
TCP 10.2.56.38:9763 192.168.23.23:49156 ESTABLISHED 4600
TCP 10.2.56.38:10267 125.39.132.161:80 ESTABLISHED 10772
TCP 10.2.56.38:10816 60.205.204.27:80 ESTABLISHED 10872
TCP 127.0.0.1:443 127.0.0.1:7216 ESTABLISHED 8108
TCP 127.0.0.1:2002 127.0.0.1:2003 ESTABLISHED 11292
TCP 127.0.0.1:2003 127.0.0.1:2002 ESTABLISHED 11292
TCP 127.0.0.1:2013 127.0.0.1:2014 ESTABLISHED 9600
TCP 127.0.0.1:2014 127.0.0.1:2013 ESTABLISHED 9600
TCP 127.0.0.1:2015 127.0.0.1:2016 ESTABLISHED 12948
TCP 127.0.0.1:2016 127.0.0.1:2015 ESTABLISHED 12948
TCP 127.0.0.1:2040 127.0.0.1:2041 ESTABLISHED 13960
TCP 127.0.0.1:2041 127.0.0.1:2040 ESTABLISHED 13960
TCP 127.0.0.1:2109 127.0.0.1:2110 ESTABLISHED 15092
TCP 127.0.0.1:2110 127.0.0.1:2109 ESTABLISHED 15092
TCP 127.0.0.1:2349 127.0.0.1:50051 ESTABLISHED 6308
TCP 127.0.0.1:2566 127.0.0.1:30031 ESTABLISHED 10624
TCP 127.0.0.1:3032 127.0.0.1:3033 ESTABLISHED 20276
TCP 127.0.0.1:3033 127.0.0.1:3032 ESTABLISHED 20276
TCP 127.0.0.1:3517 127.0.0.1:3518 ESTABLISHED 18200
TCP 127.0.0.1:3518 127.0.0.1:3517 ESTABLISHED 18200
TCP 127.0.0.1:3768 127.0.0.1:3769 ESTABLISHED 14076
TCP 127.0.0.1:3769 127.0.0.1:3768 ESTABLISHED 14076
TCP 127.0.0.1:3854 127.0.0.1:3855 ESTABLISHED 17380
TCP 127.0.0.1:3855 127.0.0.1:3854 ESTABLISHED 17380
TCP 127.0.0.1:4895 127.0.0.1:4896 ESTABLISHED 15524
TCP 127.0.0.1:4896 127.0.0.1:4895 ESTABLISHED 15524
TCP 127.0.0.1:5320 127.0.0.1:5321 ESTABLISHED 16736
TCP 127.0.0.1:5321 127.0.0.1:5320 ESTABLISHED 16736
TCP 127.0.0.1:6688 127.0.0.1:10803 ESTABLISHED 10872
TCP 127.0.0.1:6688 127.0.0.1:10824 ESTABLISHED 10872
TCP 127.0.0.1:6688 127.0.0.1:10841 ESTABLISHED 10872
TCP 127.0.0.1:6688 127.0.0.1:10849 ESTABLISHED 10872
TCP 127.0.0.1:6689 127.0.0.1:10819 ESTABLISHED 10672
TCP 127.0.0.1:7187 127.0.0.1:443 TIME_WAIT 0
TCP 127.0.0.1:7216 127.0.0.1:443 ESTABLISHED 10548
TCP 127.0.0.1:8419 127.0.0.1:8420 ESTABLISHED 14716
TCP 127.0.0.1:8420 127.0.0.1:8419 ESTABLISHED 14716
TCP 127.0.0.1:10803 127.0.0.1:6688 ESTABLISHED 2256
TCP 127.0.0.1:10819 127.0.0.1:6689 ESTABLISHED 13436
TCP 127.0.0.1:10824 127.0.0.1:6688 ESTABLISHED 10672
TCP 127.0.0.1:10841 127.0.0.1:6688 ESTABLISHED 15448
TCP 127.0.0.1:10849 127.0.0.1:6688 ESTABLISHED 9772
TCP 127.0.0.1:30031 127.0.0.1:2566 ESTABLISHED 10608
TCP 127.0.0.1:50051 127.0.0.1:2349 ESTABLISHED 10608
TCP [::1]:5900 [::1]:5901 ESTABLISHED 10548
TCP [::1]:5901 [::1]:5900 ESTABLISHED 10548
TCP [::1]:7188 [::1]:8307 FIN_WAIT_2 8108
TCP [::1]:7217 [::1]:8307 ESTABLISHED 8108
TCP [::1]:8307 [::1]:7188 CLOSE_WAIT 8108
TCP [::1]:8307 [::1]:7217 ESTABLISHED 8108

这里主要是通过过滤进程 ID 来实现快速定位的。连接也可以被主动关闭,这需要使用下面的重定向语法(其实就是关闭普通文件):

bash;gutter:false;
exec N < &-

其中 N 就是刚才打开的文件句柄,可以用 > 等效替换

Original: https://www.cnblogs.com/goodcitizen/p/monitor_protocol_on_tcp_by_shell.html
Author: goodcitizen
Title: 用 shell 脚本做 tcp 协议模拟

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/577599/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 闪存和SSD存储之间有什么区别?

    PC硬件术语经常被互换使用,其缩写被削减,或者对同一组件有多个词。以DRAM/RAM/memory为例。这三个词都是指同一个PC组件,它被安装在CPU插座旁边的瘦小插槽中&#821…

    Linux 2023年6月7日
    0169
  • redis导致的错误错误

    ==========双预防系统启动成功========== 14:42:39.821 [http-nio-9217-exec-1] INFO o.a.c.c.C.[.[.[/] -…

    Linux 2023年5月28日
    0154
  • 搭建Nginx四层反向代理

    需求背景: 前段时间公司因为业务需求需要部署一个正向代理,我已经分享出来了https://www.cnblogs.com/Dfengshuo/p/11911406.html,现有因…

    Linux 2023年6月8日
    0112
  • shell join详解

    首先贴一个,join –help 然后来理解下。 join 【命令选项】 文件1 文件2 //命令选项可以很多, 但文件只能是两个 先从重要的开始说,join 的作用是…

    Linux 2023年5月28日
    073
  • 【原创】Linux PCI驱动框架分析(一)

    背景 Read the fucking source code! –By 鲁迅 A picture is worth a thousand words. –…

    Linux 2023年6月8日
    0119
  • shell编程学习

    在一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash。 ! 告诉系…

    Linux 2023年5月28日
    092
  • 《Redis开发与运维》——(五)Redis持久化(脑图)

    posted @2021-01-09 15:04 雪山上的蒲公英 阅读(122 ) 评论() 编辑 / 返回顶部代码 / Original: https://www.cnblogs…

    Linux 2023年5月28日
    090
  • CentOS导入CA证书

    把CA证书放到如下目录 /etc/pki/ca-trust/source/anchors 再命令行运行 /bin/update-ca-trust 如下所示的操作步骤 删除证书只需要…

    Linux 2023年6月6日
    094
  • docker的基本使用

    一、 实验前置知识 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器是…

    Linux 2023年6月13日
    079
  • OrchardCore Headless建站

    说到CMS系统,可能大家都能想起 WordPress和 Drupal之类的框架,作为.NET爱好者,一般也是知道一些基于.NET的CMS框架的,典型的比如 DNN、 Umbraco…

    Linux 2023年6月6日
    0101
  • Harbor部署

    harbor 无论是使用Docker-distribution去自建仓库,还是通过官方镜像跑容器的方式去自建仓库,通过前面的演示我们可以发现其是非常的简陋的,还不如直接使用官方的D…

    Linux 2023年6月7日
    0102
  • Ruby快速入门

    推荐网站:http://ruby-for-beginners.rubymonstas.org/index.html源码参考:https://gitee.com/komavideo/…

    Linux 2023年6月14日
    096
  • Redis中使用redis-cli及密码登录

    使用redis-cli登录后如果Redis中设置了密码那么输入密码可能会出现: NOAUTH Authentication required的错。 这个时候可以输入:auth pa…

    Linux 2023年5月28日
    093
  • oracle删除超过N天数据脚本

    公司内做的项目是工厂内的,一般工厂内数据要求的是实时性,很久之前的数据可以自行删除处理,我们数据库用的oracle,所以就想着写一个脚本来删除,这样的话,脚本不管放在那里使用都可以…

    Linux 2023年6月7日
    0113
  • 【设计模式】Java设计模式-原型模式

    【设计模式】Java设计模式 – 原型模式 😄 不断学习才是王道🔥 继续踏上学习之路,学之分享笔记👊 总有一天我也能像各位大佬一样🏆原创作品,更多关注我CSDN: 一个…

    Linux 2023年6月6日
    0119
  • 美团笔试(22.03.19)

    代码题 一共五道代码题,看了前面三道,ac了三道,后面两道题没有时间看,此处将对前三题进行记录总结,后附代码。 题意:给定一组n个商品的价格,下单购买商品时,必须购买前i个商品,即…

    Linux 2023年6月13日
    098
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球