那些很重要,但是不常用的技术,websocket( 三 )

协议具体实现前提:本人最近做的项目 , 服务器端用的是C++写的 , 而与客户端交互用的是websocket , 服务器端要想正常的使用数据 , 必须要对websocket协议进行解析 。
WebSocket数据格式
那些很重要,但是不常用的技术,websocket文章插图

  1. FIN:表示这个数据是不是接收完毕 , 为1表示收到的数据是完整的 , 占1bit
  2. RSV1~3:用于扩展 , 通常都为0 , 各占1bit
  3. OPCODE:表示报文的类型 , 占4bit 0x00:标识一个中间数据包0x01:标识一个text数据包0x02:标识一个二进制数据包0x03~07:保留0x08:标识一个断开连接数据包0x09:标识一个ping数据包0x0A:标识一个pong数据包0x0B~F:保留
  4. MASK:用于表示数据是否经常掩码处理 , 为1时 , Masking-key即存在 , 占1bit
  5. Payload len:表示数据长度 , 即Payload Data的长度 , 当Payload len为0~125时 , 表示的值就是Payload Data的真实长度;当Payload len为126时 , 报文其后的2个字节形成的16bits无符号整型数的值是Payload Data的真实长度(网络字节序 , 需转换);当Payload len为127时 , 报文其后的8个字节形成的64bits无符号整型数的值是Payload Data的真实长度(网络字节序 , 需转换);
  6. Masking-key:掩码 , 当Mask为1时存在 , 占4字节32bit
  7. Payload Data:表示数据
C++对websocket协议处理/*** @brief getWSFrameData 解析websocket的协议包 , 不能解决粘包半包问题* @param msg 待解析的数据* @param msgLen 待解析的数据长度* @param outBuf 解析完成数据* @return*/int unPackingWSFrameData(char *msg,int msgLen,std::vector }uint8_t opcode_ = 0;uint8_t mask_ = 0;uint8_t masking_key_[4] = {0,0,0,0};uint64_t payload_length_ = 0;int pos = 0;//Opcodeopcode_ = msg[pos] pos++;//MASKmask_ = (unsigned char)msg[pos] >> 7;//Payload lengthpayload_length_ = msg[pos] pos++;if(payload_length_ == 126){uint16_t length = 0;memcpy(pos += 2;payload_length_ = ntohs(length);}else if(payload_length_ == 127){uint32_t length = 0;memcpy(pos += 8;payload_length_ = ntohl(length);}//Masking-keyif(mask_ == 1){for(int i = 0; i < 4; i++){masking_key_[i] = msg[pos + i];}pos += 4;}//取出消息数据if (msgLen >= pos + payload_length_ ){outBuf.clear();if(mask_ != 1){char* dataBegin = msg + pos;outBuf.insert(outBuf.begin(), dataBegin, dataBegin+payload_length_);}else{for(uint i = 0; i < payload_length_; i++){int j = i % 4;outBuf.push_back(msg[pos + i] ^ masking_key_[j]);}}}else{//此时包长小于报文中记录的包长return -2;}//断开连接类型数据包if ((int)opcode_ == 0x8)return -1;return 0;}以上函数即实现了对收到websocket数据的解析 , 返回结果为:vectoroutput;
通常会在函数外面对此进行转换为char* , 方便我们使用 , 见下:
vectoroutput;char* out = 当然 , 现在的解析还不是完美的解决方法 , 因为在实际的使用当中 , 会存在接收的包粘包 , 半包等等问题 , 而以上函数只能解决收到包正好是一个完整的包的情况;具体解决粘包半包问题 , 留待下次博客吧!
参考资料:后台私信“资料”送结尾:只为记录 , 只为分享! 愿所写能对你有所帮助 。 不忘记点个赞 , 谢谢~
【那些很重要,但是不常用的技术,websocket】后台私信可以领取 内容包括:C/C++ , Linux , Nginx , ZeroMQ , MySQL , Redis , fastdfs , MongoDB , ZK , 流媒体 ,WebRTC, CDN , P2P , K8S , Docker , Golang, TCP/IP , MTK , 嵌入式,协程 , DPDK等等。