Websocket(websocket自定义协议)

是基于TCP的

tcp特征:

  • 我发数据对端可以接收到,对端发数据我可以收到
  • 先发先收到,后发后收到

使用websocket客户端发给服务器数据,服务器回客户端返回数据流程(自定义websocket协议需要从下三个部分考虑)

1、握手  handshake

2、发送数据和接收数据

3、断开(客户端点击断开按钮)

一、握手

问:Tcp已经握手了,为什么需要websocket需要再次握手?

答:

1、握手过程

2、服务端如果根据key换算生成一个key返回给客户端进行身份验证

过程: 身份验证的key的换算过程 

1、接收到的key与一个guid字符连接

问:guid是固定的且公开的,那么为什么必须要这步呢?

答:起到填充的作用,避免传的字符少的时候不方便进行哈希

2、对新的字符进行哈希

 3、做完哈希后得到sha,对哈希后的值进行base64编码

 4、最后得到一个字符返回给客户端(也就是Sec-WebSocket-Accept:……)

 

二、发送数据过程

考虑(发送长度问题、明文还是密文

websocket头(协议)+(payload)数据

a、不出现分包和粘包情况:

只有在发送数据,每个数据包很小,每个包之间加个延迟发送,就不用考虑分包粘包

b、数据包太大肯定要考虑分包和粘包:(websocket协议来解决分包粘包)

分包和粘包解决:1、对每个数据包前后(开始和结尾)加个分隔符   

              2、定一个包头(包头里面有包总长度)   下面为包头组成详解

1、客户端向服务端发送数据(服务端得到的信息)

客户端:

 服务端:

 2、websocket协议(包头)

通过上面传输过程得知上面发送数据后,多出来的6个字节,那这个websocket的头就是6个字节(字节总数-发送数据字节数=websocket协议头)

包头的组成部分

  •   标识     =>可以根据自己喜好定义一些标识
  •        长度      =>这个长度有说法,不同的长度会影响这个websocket协议的字节长度(详看下图剖析)
  •        masking-key    =>明文、暗文的key   1密文  0明文

2-2、叙述上面发送数据案例多的6个字节是什么?

1Byte=8bit                      32bit=4字节

 图剖析:

剖析一:

协议头是由这部分组成  

剖析二:

剖析三:

由剖析二剖析可以看到红框内一共是14个字节,但是其中有两个if

 

剖析四:

其中包含有两个if,payload长度满足一定条件才会算上这个字节

 

三种情况:根据payload长度判断

 

 

 所以上面发送案例中:接收到了13个字节,实际发送给的数据7个字节,多出来的6个字节就是websocket协议头的长度

如图:

 综上所述:

一个websocket包最大可以传输73bits     payload length=73bits

playload length三种情况

 

 

 

2.3 发送数据为明文还是暗文

密文:

        对称加密:1、base64、对每个字节取反     (弊端:A客户端的密文在B客户端也可以被解出来)

           2、异或      (好处:A客户端的密文在B客户端不可以被解出来)

             用法:对每一个字节流做个异或

 

传递一个32bit(4字节)的value对数据进行异或 :(可以是随机的)

异或操作公式:

 

异或案例解释:循环异或:案例说明

(异或中的maskkey的值是在协议头中的)

 

发送数据公式参数剖析: 

recv(fd,buffer,length,0)  

fd:

buffer:

length:是buffer的长度

  • 若定义char buffer[1024] ,length就是填1024
  • 填长度的意义是防止包越界

0:0明文或1暗文

三、断开

websokcet为什么单独定义一个终止包?

客户端点击断开:发送的内容如下图(只发了一个协议头,内容data为空)  --终止包

 

 接收包的协议头第一个bit(FIN)为1表示断开websocket

需要两步:1、协议头中的FIN为1,发送一个终止包,表示:先把服务端关于websocket的资源清空

                   2、发送FIN后,第二步调用close  ,表对应示四次挥手的断开

 

posted @ 2023-02-12 18:53  じ逐梦  阅读(741)  评论(0编辑  收藏  举报