Websocket帧
在浏览器升级为websocket协议,数据的传输就会开始传输websocket帧
第一个字节:
2
FIN:1或0,1代表最后分片,0代表后面还有
rsv1/2/3:扩展保留位,必须为0,除非协商了扩展。
Opcode:操作码,例如:0x0– 继续帧 ,0x1– 文本帧
第2个字节
MASK:负载数据是否掩码,0代表无,1代表有,客户端到服务端一定要掩码,服务端到客户端一定不需要
Payload length:1.负载数据长度(1-125),直接将长度存在这里 2.负载数据长度(126-65535),存126 3.负载数据大于65535,存127
Payload length根据Payload length的不同取值来决定大小
Payload length为126时,16bit(2字节)
Payload length为127时,64bit(8字节)
当为其他值,0bit
Masking-key根据MASK的值决定是否存在
这里存放了4个字节码,后面的数据需要通过这个码来解码
浏览器发送数据的时候会使用这个4个字节码,对数据进行一次异或操作,在服务端需要对数据在进行一次异或操作,就会还原数据
后面就是数据实际存储位置了
以下是我的python代码模拟
def websockencode(self,mes): date=bytes([0b10000001,len(mes)]) date+=mes.encode() return date def websockdecode(self,data): if not(data[0]>>7)&1:return mask=(data[1]>>7)&1 l=data[1]&0b01111111 head_len=2 if l<126: lens=l elif l==126: bt=data[2:4] head_len=4 lens=bt[0]*256+bt[1] elif l==127: lens=0 j=1 for i in range(9,1,-1): lens+=data[i]*j j*=256 head_len=10 maskdata=data[head_len:head_len+4] head_len+=4 mes=data[head_len:head_len+lens] return bytes([mes[i]^maskdata[i%4] for i in range(len(mes))]) def first_link_res(self,date): httplines=date.split("\r\n") KEY="" for i in httplines: if i.startswith("Sec-WebSocket-Key"): KEY=i.split(": ")[1] print(KEY) acc=base64.b64encode(hashlib.sha1((KEY+self.WEBSOCKKEY).encode()).digest()) response = ( "HTTP/1.1 101 Switching Protocols\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" f"Sec-WebSocket-Accept: {acc.decode()}\r\n" "\r\n" ) return response最后是完整图片
