如果对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;协议重发出现问题;
最终确认订阅消息重发了,重发的消息出现问题导致报错协议错误,服务端主动断开连接,问题得到定位。
来源:oschina
链接:https://my.oschina.net/u/4326248/blog/4295997