看见协议,浅析TCP、HTTP、MQTT

如果对tcp还不了解的,可以看看计算机网络基础简单了解一下;

如果对tcp的深入感兴趣,看了上一篇还不过瘾的可以看吊打面试官!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题

好了,如果看回来了我们来进入正题,首先了解一下wireshark

抓包工具wireshark

首先去官网下载对应安装包https://www.wireshark.org/download.html 

window安装下一步下一步、默认就行,其中有一个统计usb的包是否安装,可以不装

启动服务,第一步选择网卡

常用知识

不同的协议有不同的着色规则;点击  视图-->着色规则 查看

过滤栏包含:保存,停止、重新捕获、切换网卡等等

数据过滤

通过数据过滤,来查看我们的请求的具体执行情况

ip.addr == 216.58.200.42 根据ip筛选

ip.addr == 10.200.60.88 and http 根据ip和协议筛选,好像还有http2

 看见HTTP协议

首先,从之前的两篇TCP博客拿一些TCP协议的基本概念,方便后面的理解

准备一个简单的http接口如图:

请求地址 http://127.0.0.1:11003/demo/servicea/person/123  ,响应很简单

 

使用postman来请求,开启wireshark的抓包,然后通过ip.addr == 10.200.60.88过滤指定请求

 HTTP请求分析

## tcp摘要信息
54251 → 11003 [SYN] Seq=0 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1
54251 → 11003 端口号:源端口--->目标端口
[SYN] client-->server [SYN、ACK] server响应ACK [ACK] 客户端确认ack、连接建立
Seq : 消息序列号、【基本上针对的ack = seq+1】
Win: TCP 窗口大小;最大65535=64kb
Len: 消息长度;len = TCP数据长度 = IP总长度-IP首部长度-TCP首部长度
Mss: 最大报文段长度;规定的最大报文长度;
Ws: 窗口缩放调整因子;ws * win = 时间窗口长度  
SACK_PERM : SACK选项,这里等于1表示开启 SACK。

 明显看到133-134-135是tcp的三次握手;然后136是http请求:client-->server

137是针对136的http的ack确认,140的[PSH,ACK]是针对136的http消息体响应

141是服务端对客户端的响应server-->client;142是客户端对服务端的确认。

http1.1默认开启keepAlive;后面就是keepalive;

keepalive使用心跳检查,client-->server ;服务端响应ack;

间隔固定的时间去重复这个过程;

TCP的[PSH,ACK]

网上对TCP segment of a reassembled PDU解释不清不楚;

使用postman在body放无效数据来观察

对面上面两张 wireshark抓包的图:可以看到客户端包含数据时候,会发送[PSH,ACK];没有数据的情况直接使用http请求

使用google浏览器试一试,发现执行了两次tcp三次握手,有博客说为了google可用性设计、供参考;

 

 一次MQTT协议异常的排查

对mqtt不了解的可以看看MQTT和协议笔记

mqtt是一个工业环境下的mq协议,需要mqtt server端,一端发消息,一端收消息;

某个项目中使用mqtt协议,同事排查发现问题,发现mqtt server挂了重启以后,客户端会一直重连;但是一直重连不上

表现为:连接成功--->订阅----阻塞---订阅成功---断开连接 ---->重连成功---->订阅      一直循环

由于不方便贴源码,直接说造成这次后果的原因

1、重连以后会重新订阅topic、订阅调用阻塞的await方法导致无法处理订阅的ack响应,阻塞10秒

2、mqtt client有个定时器发送消息失败(未接到响应ack)会重新发送消息,默认10秒每次加5秒去重发消息;

但是重发的消息是针对PUBLISH的消息,导致重发订阅消息协议错误,服务端断开连接

## mqtt消息类型回顾
CONNECT – 连接服务端
CONNACK – 确认连接请求
PUBLISH – 发布消息
PUBACK –发布确认
PUBREC – 发布收到(QoS 2,第一步)
PUBREL – 发布释放(QoS 2,第二步)
PUBCOMP – 发布完成(QoS 2,第三步)
SUBACK – 订阅确认
UNSUBSCRIBE –取消订阅
UNSUBACK – 取消订阅确认
PINGREQ – 心跳请求
PINGRESP – 心跳响应
DISCONNECT –断开连接

mqtt server mosquitto报错: Client netty-mqtt/08elI9Go disconnected due to protocol error 

再此开启wireshark的抓包,信息如下

简单分析:

118~120 tcp三次握手

121~124 mqtt的连接和确认

135~138 mqtt的订阅确认,topic是mqtt-test

147~150 tcp的四次挥手

将Mqtt服务关闭,客户端有重连机制去重新连接服务端,发送tcp的syn;

[RST,ACK]服务端断开连接;[TCP Retransmission] 客户端重传

服务端发送 tcp rst终止重连,TCP重传一次;继续这个过程

等服务端正常启动,又进入上面的流程tcp三次握手,建立mqtt connect;

通过比对第一次正常订阅,和第二次异常订阅导致服务端关闭连接的信息;

mqtt 订阅的消息头,一个是82,一个是8a;协议重发出现问题;

最终确认订阅消息重发了,重发的消息出现问题导致报错协议错误,服务端主动断开连接,问题得到定位。 

猜你喜欢

转载自blog.csdn.net/Zzhou1990/article/details/106410952