c++ 构造加密数据发给websocket服务端

本文深入探讨了WebSocket协议的工作原理,包括数据帧的编码与解码过程,以及关键字段如FIN、RSV、opcode和mask的使用。通过具体示例展示了如何在C++中实现WebSocket数据的发送与接收。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

demo:

1、调用发送接口内容

uint8_t send_buf_[1024] = {0};
    
    string message = temp;
    
    Protocol protocol;
    protocol.FIN = 1;
    protocol.opcode = protocol.TEXT_FRAME;
    protocol.mask = 1;
    uint8_t* ends = protocol.encode(message.begin(), message.end(), send_buf_);
    
    pSock->SendBin(0, 0, (const char*)send_buf_, ends - send_buf_);

2。引入头文件

#pragma once

#include <stdint.h>
#include <iostream>

namespace websocket {

namespace internal {

/**
 * Decode byte sequence to 64bit integer.
 *
 * @pre sequence must have length larger than or equal to 8.
 */
template <class InputIterator>
inline uint64_t decode_uint64(InputIterator first) {
  uint64_t res = 0;
  int shift = 64;
  while (shift) {
    shift -= 8;
    res |= static_cast<uint64_t>(*first) << shift;
    ++first;
  }
  return res;
}

/**
 * Data transfer protocol based on RFC6455.
 *
 * 0                   1                   2                   3
 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 * +-+-+-+-+-------+-+-------------+-------------------------------+
 * |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
 * |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
 * |N|V|V|V|       |S|             |   (if payload len==126/127)   |
 * | |1|2|3|       |K|             |                               |
 * +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
 * |     Extended payload length continued, if payload len == 127  |
 * + - - - - - - - - - - - - - - - +-------------------------------+
 * |                               |Masking-key, if MASK set to 1  |
 * +-------------------------------+-------------------------------+
 * | Masking-key (continued)       |          Payload Data         |
 * +-------------------------------- - - - - - - - - - - - - - - - +
 * :                     Payload Data continued ...                :
 * + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
 * |                     Payload Data continued ...                |
 * +---------------------------------------------------------------+
 */
struct Protocol {
  static const std::size_t MAX_FRAMING_HEADER_LEN = 14;
    
  bool FIN;
  bool RSV1;
  bool RSV2;
  bool RSV3;
  bool mask;

  enum opcode_type {
    CONTINUATION = 0x0,
    TEXT_FRAME = 0x1,
    BINARY_FRAME = 0x2,
    CLOSE = 0x8,
    PING = 0x9,
    PONG = 0xa,
  } opcode;
  uint8_t masking_key[4];  // TODO: use random
  uint8_t payload_len;     // 0~127
  uint64_t length;         // length of payload

  Protocol()
      : FIN(0),
        RSV1(0),
        RSV2(0),
        RSV3(0),
        mask(0),
        opcode(CONTINUATION),
        payload_len(0),
        length(0) {
    masking_key[0] = 0x12;
    masking_key[1] = 0x34;
    masking_key[2] = 0x56;
    masking_key[3] = 0x78;
  }

  template <class InputIterator>
  uint64_t size_expected(InputIterator first, InputIterator last) {
    const uint64_t size = last - first;
    uint64_t res = 2;

    res += mask ? 4 : 0;
    res += size;
    if (126 <= size && size <= 0xff) {
      size += 2;
    } else if (0xff < size) {
      size += 8;
    }
    return size;
  }

  template <class OutputIterator, class InputIterator>
  OutputIterator encode(InputIterator first, InputIterator last,
                        OutputIterator result) const {
    *result = FIN << 7 | RSV1 << 6 | RSV2 << 5 | RSV3 << 4 | opcode;
    ++result;

    *result = mask << 7;

    const std::size_t size = last - first;
    if (size <= 125) {
      *result |= size;
      ++result;
    } else if (size <= 0xffff) {
      *result |= 126;
      ++result;
      *result = size >> 8;
      ++result;
      *result = size & 0xff;
      ++result;
    } else {
      *result |= 127;
      ++result;

      std::size_t shift = 64;
      while (shift) {
        shift -= 8;
        *result = size >> shift & 0xff;
        ++result;
      }
    }

    if (mask) {
      *result = masking_key[0];
      ++result;

      *result = masking_key[1];
      ++result;

      *result = masking_key[2];
      ++result;

      *result = masking_key[3];
      ++result;

      std::size_t count = 0;
      while (first != last) {
        *result = *first ^ masking_key[count & 0x3];
        ++first;
        ++result;
        count = (count + 1) & 0x03;
      }
    } else {
      while (first != last) {
        *result = *first;
        ++first;
        ++result;
      }
    }
    return result;
  }

  /**
   * Decode header part of data.
   */
  template <class InputIterator>
  InputIterator decode_header(InputIterator input) {
    FIN = *input >> 7 & 0x01;
    RSV1 = *input >> 6 & 0x01;
    RSV2 = *input >> 5 & 0x01;
    RSV3 = *input >> 4 & 0x01;
    opcode = static_cast<opcode_type>(*input & 0x0f);
    ++input;

    mask = *input & 0x80 ? 1 : 0;
    payload_len = *input & 0x7f;  // 7bit
    ++input;

    return input;
  }

  template <class InputIterator>
  InputIterator decode_expandables(InputIterator input) {
    if (payload_len <= 125) {
      length = payload_len;
    } else if (payload_len == 126) {
      length = *input << 8;
      ++input;
      length |= *input & 0xff;
      ++input;
    } else if (payload_len == 127) {
      length = decode_uint64(input);
    } else {
      // TODO: error
    }

    if (mask) {
      masking_key[0] = *input;
      ++input;
      masking_key[1] = *input;
      ++input;
      masking_key[2] = *input;
      ++input;
      masking_key[3] = *input;
      ++input;
    }
    return input;
  }

  /**
   * Decode payload data
   */
  template <class OutputIterator, class InputIterator>
  OutputIterator decode_payload(InputIterator input,
                                OutputIterator result) const {
    for (uint64_t i = 0; i < length; i++) {
      *result = mask ? *input ^ masking_key[i & 0x3] : *input;
      ++result;
      ++input;
    }
    return result;
  }

  /**
   * Decode header and payload
   *
   * TODO: test me
   */
  template <class OutputIterator, class InputIterator>
  OutputIterator decode(InputIterator input, OutputIterator result) {
    input = decode_header(input);
    input = decoded_expantables(input);
    return decode_payload(result);
  }

  /**
   * Length of expandable part: masking_key and length
   */
  uint32_t expandable_length() const {
    return mask ? 4 : 0 + payload_len == 126 ? 2 : payload_len == 127 ? 8 : 0;
  }
};

}  // namespace internal

}  // namespace websocket

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值