websocket突破了HTTP协议单向性的缺陷,基于HTTP协议构建了双向通信的通道,使服务端可以主动推送数据到前端,解决了前端不断轮询后台才能获取后端数据的问题,所以在小程序和H5应用中被广泛使用。本文主要集合报文分析对于websocket的状态机进行讲解。
1)websocket状态机
websocket状态机相对于非常经典的TCP状态机来说非常的简单,包括五种状态:INITIAL、CONNECTING、OPEN、CLOSING和CLOSED。其中客户端涉及五种状态:INITIAL、CONNECTING、OPEN、CLOSING和CLOSED,服务端涉及四种状态:INITIAL、OPEN、CLOSING和CLOSED。状态变迁过程如下:
websocket建立过程中状态的变化如下所述:
1)客户端调用connect发起连接,则经过INITIAL进入CONNECTING状态,并且发起握手请求
2)服务端websocket启动进入INITIAL状态
3)服务端接收到客户端的握手请求后回复握手应答,状态变迁为OPEN
4)客户端接收到服务端的握手应答后,状态也变迁到OPEN
(至此客户端和服务端的websocket连接正式链接,可以双向通信了)
5)任何一方都可以关闭websocket连接。发起关闭连接的一方,调用close将发送关闭帧到对端,状态变迁到CLOSING
6)接收到关闭帧的一方状态也变迁到CLOSING,,并发起拆除TCP连接的请求(发送FIN分组,然后经过四次握手后完成TCP连接的关闭操作。
2)websocket协议分析
websocket协议本身是基于TCP的协议,但其中的握手协议使用了HTTP协议,以下是一个websocket客户端与服务端建立连接,连接建立后服务端发送一个票据到客户端,然后客户端发送hello world后,再关闭websocket,报文全貌如下:
前3行是标准的TCP三次握手,建立TCP连接。
第4行到第6行是websocket握手过程,握手完成建立了WEBSOCKET连接(此时客户端和服务端状态机均为OPEN状态)
第7行和第8行是服务端发送票据的报文。
第9行和第10行是客户端发送hello world到服务端
第11行到13行是websocket关闭过程。第11行是客户端发起关闭请求帧(自身进入CLOSING状态),第12行是服务端对关闭帧的确认,第13行是服务端发送关闭请求帧(服务端进入CLOSING状态)
第14行到第17行是服务端发起的关闭TCP连接的过程。TCP连接关闭后,两个状态机均进入CLOSED状态。
3)报文分析
以下仅对websocket相关报文进行分析,TCP的连接建立、关闭和ACK报文不再关注。
客户端发起握手报文如下:
服务端发起握手报文如下:
建立websocket连接后,服务端发送的令牌报文如下:
服务端发送hello word的报文如下:
客户端发送关闭帧报文如下:
服务端发送关闭帧报文如下: