WebSocket数据封包解包

版权声明: https://blog.csdn.net/qq_28710983/article/details/83151558

websocket和TCP/IP多了一个握手协议(ws协议不用2字节长度加数据体的协议)

1、ws_protocol类

class ws_protocol{
public:
	static bool ws_shake_hand(session* s, char* body, int len);
	static bool read_ws_header(unsigned char* recv_data, int recv_len, int* pkg_size, int* out_header_size);
	static void parser_ws_recv_data(unsigned char* raw_data, unsigned char* mask, int raw_len);
	static unsigned char* package_ws_send_data(const unsigned char* raw_data, int len, int* ws_data_len);
	static void free_package_data(unsigned char* ws_pkg);
};

2、ws_shake_hand 握手协议,客户端向服务器发送握手请求报文

        GET /chat HTTP/1.1
        Host: server.example.com
        Upgrade: websocket
        Connection: Upgrade
        Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
        Origin: http://example.com
        Sec-WebSocket-Protocol: chat, superchat
        Sec-WebSocket-Version: 13

3、当服务器收到报文请求时,解析报文,把Sec-WebSocket-Key加上migic(s3pPLMBiTxaQ9kYGzzhZRbK+xOo=258EAFA5-E914-47DA-95CA-C5AB0DC85B11)进行sha1加密,然后再base64编码后,发送给客户端

        HTTP/1.1 101 Switching Protocols
        Upgrade: websocket
        Connection: Upgrade
        Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
        Sec-WebSocket-Protocol: chat

s3pPLMBiTxaQ9kYGzzhZRbK+xOo=这段报文就是Keymigic加密后编码而成的,当客户端收到上面报文websocket握手成功即可发送数据

4、read_ws_header读取头信息websocket数据收发协议

  1. Websocket协议第一个字节是0x81或0x82,第二个字节是长度head_size = 2
  2. 如果第二个字节小于125,表示后面就有多少个字节的数据 head_size = 2 + 4
  3. 如果第二个字节等于126,表示后面2字节是后面数据的长度 head_size = 2+2+4
  4. 如果第二个字节等于127,表示后面8字节是后面的长度 head_size=2+8+4
  5. 长度后面紧跟4个字节的umask,
  6. umask后紧跟真实数据

5、ws数据发送协议打包(发送给客户端的不需要umask即可)

unsigned char* ws_protocol::package_ws_send_data(const unsigned char* raw_data, int len, int* ws_data_len){
	int head_size = 2;
	if (len > 125 && len < 65536) {
		head_size += 2;
	}
	else if (len >= 65536) {
		head_size += 8;
		return NULL;
	}
	unsigned char* data_buf = (unsigned char*)cache_alloc(wbuf_allocer, head_size + len);
	data_buf[0] = 0x81;
	if (len <= 125) {
		data_buf[1] = len;
	}
	else if (len > 125 && len < 65536) {
		data_buf[1] = 126;
		data_buf[2] = (len & 0x0000ff00) >> 8;
		data_buf[3] = (len & 0x000000ff);
	}
	memcpy(data_buf + head_size, raw_data, len);
	*ws_data_len = (head_size + len);
	return data_buf;
}

 

猜你喜欢

转载自blog.csdn.net/qq_28710983/article/details/83151558