栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

深入浅出websocket

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

深入浅出websocket

本篇博文主要是提供了一个基于tcp封装的websocket服务端,没有使用任何的网络库,这样便于自我学习,关于这个协议的一些概念的话,大家可以执行百度了解。
客户端的话,大家可以找一些在线网站模拟websocket客户端即可。代码的话,由select+tcp改装而成,主要适用于windows平台,大家如果有兴趣也可以使用epoll来实现。下面给出具体的代码,具体可以用vs进行单步调试观察一下包的格式,这样对于理解这个协议的理解是非常有帮助的。

//base64.cpp

#include "base64.h"
#include 

static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";


static inline bool is_base64(unsigned char c) {
    return (isalnum(c) || (c == '+') || (c == '/'));
}

std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
    std::string ret;
    int i = 0;
    int j = 0;
    unsigned char char_array_3[3];
    unsigned char char_array_4[4];

    while (in_len--) {
        char_array_3[i++] = *(bytes_to_encode++);
        if (i == 3) {
            char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
            char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
            char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
            char_array_4[3] = char_array_3[2] & 0x3f;

            for (i = 0; (i < 4); i++)
                ret += base64_chars[char_array_4[i]];
            i = 0;
        }
    }

    if (i)
    {
        for (j = i; j < 3; j++)
            char_array_3[j] = '';

        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
        char_array_4[3] = char_array_3[2] & 0x3f;

        for (j = 0; (j < i + 1); j++)
            ret += base64_chars[char_array_4[j]];

        while ((i++ < 3))
            ret += '=';

    }
    return ret;
}

std::string base64_decode(std::string const& encoded_string) {
    size_t in_len = encoded_string.size();
    int i = 0;
    int j = 0;
    int in_ = 0;
    unsigned char char_array_4[4], char_array_3[3];
    std::string ret;

    while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
        char_array_4[i++] = encoded_string[in_]; in_++;
        if (i == 4) {
            for (i = 0; i < 4; i++)
                char_array_4[i] = base64_chars.find(char_array_4[i]);

            char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
            char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
            char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

            for (i = 0; (i < 3); i++)
                ret += char_array_3[i];
            i = 0;
        }
    }

    if (i) {
        for (j = i; j < 4; j++)
            char_array_4[j] = 0;

        for (j = 0; j < 4; j++)
            char_array_4[j] = base64_chars.find(char_array_4[j]);

        char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
        char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
        char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

        for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
    }

    return ret;
}

base64.h

#pragma once
#include 

std::string base64_encode(unsigned char const*, unsigned int len);
std::string base64_decode(std::string const& s);

//sha1.cpp

#include "sha1.h"


SHA1::SHA1()
{
    Reset();
}


SHA1::~SHA1()
{
    // The destructor does nothing
}


void SHA1::Reset()
{
    Length_Low          = 0;
    Length_High         = 0;
    Message_Block_Index = 0;

    H[0]        = 0x67452301;
    H[1]        = 0xEFCDAB89;
    H[2]        = 0x98BADCFE;
    H[3]        = 0x10325476;
    H[4]        = 0xC3D2E1F0;

    Computed    = false;
    Corrupted   = false;
}


bool SHA1::Result(unsigned *message_digest_array)
{
    int i;                                  // Counter

    if (Corrupted)
    {
        return false;
    }

    if (!Computed)
    {
        PadMessage();
        Computed = true;
    }

    for(i = 0; i < 5; i++)
    {
        message_digest_array[i] = H[i];
    }

    return true;
}


void SHA1::Input(   const unsigned char *message_array,
                    unsigned            length)
{
    if (!length)
    {
        return;
    }

    if (Computed || Corrupted)
    {
        Corrupted = true;
        return;
    }

    while(length-- && !Corrupted)
    {
        Message_Block[Message_Block_Index++] = (*message_array & 0xFF);

        Length_Low += 8;
        Length_Low &= 0xFFFFFFFF;               // Force it to 32 bits
        if (Length_Low == 0)
        {
            Length_High++;
            Length_High &= 0xFFFFFFFF;          // Force it to 32 bits
            if (Length_High == 0)
            {
                Corrupted = true;               // Message is too long
            }
        }

        if (Message_Block_Index == 64)
        {
            ProcessMessageBlock();
        }

        message_array++;
    }
}


void SHA1::Input(   const char  *message_array,
                    unsigned    length)
{
    Input((unsigned char *) message_array, length);
}


void SHA1::Input(unsigned char message_element)
{
    Input(&message_element, 1);
}


void SHA1::Input(char message_element)
{
    Input((unsigned char *) &message_element, 1);
}


SHA1& SHA1::operator<<(const char *message_array)
{
    const char *p = message_array;

    while(*p)
    {
        Input(*p);
        p++;
    }

    return *this;
}


SHA1& SHA1::operator<<(const unsigned char *message_array)
{
    const unsigned char *p = message_array;

    while(*p)
    {
        Input(*p);
        p++;
    }

    return *this;
}


SHA1& SHA1::operator<<(const char message_element)
{
    Input((unsigned char *) &message_element, 1);

    return *this;
}


SHA1& SHA1::operator<<(const unsigned char message_element)
{
    Input(&message_element, 1);

    return *this;
}


void SHA1::ProcessMessageBlock()
{
    const unsigned K[] =    {               // Constants defined for SHA-1
                                0x5A827999,
                                0x6ED9EBA1,
                                0x8F1BBCDC,
                                0xCA62C1D6
                            };
    int         t;                          // Loop counter
    unsigned    temp;                       // Temporary word value
    unsigned    W[80];                      // Word sequence
    unsigned    A, B, C, D, E;              // Word buffers

    
    for(t = 0; t < 16; t++)
    {
        W[t] = ((unsigned) Message_Block[t * 4]) << 24;
        W[t] |= ((unsigned) Message_Block[t * 4 + 1]) << 16;
        W[t] |= ((unsigned) Message_Block[t * 4 + 2]) << 8;
        W[t] |= ((unsigned) Message_Block[t * 4 + 3]);
    }

    for(t = 16; t < 80; t++)
    {
       W[t] = CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
    }

    A = H[0];
    B = H[1];
    C = H[2];
    D = H[3];
    E = H[4];

    for(t = 0; t < 20; t++)
    {
        temp = CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
        temp &= 0xFFFFFFFF;
        E = D;
        D = C;
        C = CircularShift(30,B);
        B = A;
        A = temp;
    }

    for(t = 20; t < 40; t++)
    {
        temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
        temp &= 0xFFFFFFFF;
        E = D;
        D = C;
        C = CircularShift(30,B);
        B = A;
        A = temp;
    }

    for(t = 40; t < 60; t++)
    {
        temp = CircularShift(5,A) +
               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
        temp &= 0xFFFFFFFF;
        E = D;
        D = C;
        C = CircularShift(30,B);
        B = A;
        A = temp;
    }

    for(t = 60; t < 80; t++)
    {
        temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
        temp &= 0xFFFFFFFF;
        E = D;
        D = C;
        C = CircularShift(30,B);
        B = A;
        A = temp;
    }

    H[0] = (H[0] + A) & 0xFFFFFFFF;
    H[1] = (H[1] + B) & 0xFFFFFFFF;
    H[2] = (H[2] + C) & 0xFFFFFFFF;
    H[3] = (H[3] + D) & 0xFFFFFFFF;
    H[4] = (H[4] + E) & 0xFFFFFFFF;

    Message_Block_Index = 0;
}


void SHA1::PadMessage()
{
    
    if (Message_Block_Index > 55)
    {
        Message_Block[Message_Block_Index++] = 0x80;
        while(Message_Block_Index < 64)
        {
            Message_Block[Message_Block_Index++] = 0;
        }

        ProcessMessageBlock();

        while(Message_Block_Index < 56)
        {
            Message_Block[Message_Block_Index++] = 0;
        }
    }
    else
    {
        Message_Block[Message_Block_Index++] = 0x80;
        while(Message_Block_Index < 56)
        {
            Message_Block[Message_Block_Index++] = 0;
        }

    }

    
    Message_Block[56] = (Length_High >> 24) & 0xFF;
    Message_Block[57] = (Length_High >> 16) & 0xFF;
    Message_Block[58] = (Length_High >> 8) & 0xFF;
    Message_Block[59] = (Length_High) & 0xFF;
    Message_Block[60] = (Length_Low >> 24) & 0xFF;
    Message_Block[61] = (Length_Low >> 16) & 0xFF;
    Message_Block[62] = (Length_Low >> 8) & 0xFF;
    Message_Block[63] = (Length_Low) & 0xFF;

    ProcessMessageBlock();
}



unsigned SHA1::CircularShift(int bits, unsigned word)
{
    return ((word << bits) & 0xFFFFFFFF) | ((word & 0xFFFFFFFF) >> (32-bits));
}

//sha1.h

#ifndef _SHA1_H_
#define _SHA1_H_

class SHA1
{
    public:

        SHA1();
        virtual ~SHA1();

        
        void Reset();

        
        bool Result(unsigned *message_digest_array);

        
        void Input( const unsigned char *message_array,
                    unsigned            length);
        void Input( const char  *message_array,
                    unsigned    length);
        void Input(unsigned char message_element);
        void Input(char message_element);
        SHA1& operator<<(const char *message_array);
        SHA1& operator<<(const unsigned char *message_array);
        SHA1& operator<<(const char message_element);
        SHA1& operator<<(const unsigned char message_element);

    private:

        
        void ProcessMessageBlock();

        
        void PadMessage();

        
        inline unsigned CircularShift(int bits, unsigned word);

        unsigned H[5];                      // Message digest buffers

        unsigned Length_Low;                // Message length in bits
        unsigned Length_High;               // Message length in bits

        unsigned char Message_Block[64];    // 512-bit message blocks
        int Message_Block_Index;            // Index into message block array

        bool Computed;                      // Is the digest computed?
        bool Corrupted;                     // Is the message digest corruped?
    
};

#endif // _SHA1_H_

上面几个文件提供的接口可以用来进行数据的加密,
这个如果大家有需要可以考虑一下,具体的用法,可以看如下的文件。(当然,如果服务端使用了,客户端那么也是需要使用的)

#include "debug_log.h"

void DEBUG_LOG(const char* msg, ...) {
    char message[256] = { 0 };
    va_list args;
    va_start(args, msg);
    vsprintf(message, msg, args);
    va_end(args);
    Debug_LOG::log()->write_log(message);
}

Debug_LOG* Debug_LOG::m_log = NULL;

Debug_LOG::Debug_LOG() :
    tim(0),
    t(NULL),
    fp(NULL),
    filepath(),
    message(),
    last_log_time()
{
#ifdef __WRITE_FILE__
    create_log_file();
#endif
}

Debug_LOG::~Debug_LOG() {
#ifdef __WRITE_FILE__
    fclose(fp);
#endif
}

void Debug_LOG::create_log_file() {
    if (fp != NULL)
        fclose(fp);

    sprintf(filepath, "./log/debuglog_");
    time(&tim);
    t = localtime(&tim);
    memcpy(&last_log_time, t, sizeof(struct tm));
    sprintf(filepath + 15, "%02d_%02d", t->tm_mon + 1, t->tm_mday);
    fp = fopen(filepath, "a+");
}

Debug_LOG* Debug_LOG::log() {
    if (m_log == NULL) {
        m_log = new Debug_LOG();
    }
    return m_log;
}

void Debug_LOG::write_log(const char* msg) {
    time(&tim);
    t = localtime(&tim);
    sprintf(message, "[%02d:%02d:%02d] %sn", t->tm_hour, t->tm_min, t->tm_sec, msg);
#ifdef __WRITE_FILE__
    if (t->tm_mday != last_log_time.tm_mday || t->tm_mon != last_log_time.tm_mon
        || t->tm_year != last_log_time.tm_year)
        create_log_file();
    fwrite(message, strlen(message), 1, fp);
    fflush(fp);
#else
    printf("n%s", message);
    fflush(stdout);
#endif
}

#pragma once

#ifndef __debug_log__
#define __debug_log__

//#define __WRITE_FILE__

#include 
#include 
#include 
#include 

void DEBUG_LOG(const char* msg, ...);

class Debug_LOG 
{
private:
    Debug_LOG();
    ~Debug_LOG();
    void create_log_file();
public:
    static Debug_LOG* log();
    void write_log(const char* msg);
private:
    static Debug_LOG* m_log;
    time_t tim;
    struct tm* t;
    FILE* fp;
    char filepath[32];
    char message[256];
    struct tm last_log_time;
};

#endif

这两个是用来调试的。

//以下的代码是核心部分。

#include 
#include 
#include 
#include 
#include 
#include "debug_log.h"
#include "network_interface.h"
#include "websocket_respond.h"
#include "websocket_request.h"
#include 
#include "windows.h"
#include "time.h"
WEB_SOCKET_ISH5_MAP websocket_ish5run_map_;
WEB_SOCKET_ISH5_MAP websocket_ish5configdata_map_;
WEB_SOCKET_ISH5_MAP websocket_ish5gamedata_map_;

Network_Interface* Network_Interface::m_network_interface = NULL;

Network_Interface::Network_Interface() : listenfd_(0), websocket_handler_map_()
{
    if(init() != 0)
    {
        exit(1);
    }
}

Network_Interface::~Network_Interface() 
{
    WSACleanup();
}

void Network_Interface::run()
{
    select_loop();
}

Network_Interface* Network_Interface::get_share_network_interface()
{
    if(m_network_interface == NULL)
        m_network_interface = new Network_Interface();
    return m_network_interface;
}

int Network_Interface::init() 
{
    WSADATA wsaData;
    int err = WSAStartup(MAKEWORD(2, 2), &wsaData); 
    if(err != 0)
    {
        std::cout << "Load WinSock Failed!n";
        return -1;
    }
    listenfd_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(listenfd_ == -1) 
    {
        DEBUG_LOG("create socket error!n");
        return -1;
    }
    
    int option = 1;
    if(setsockopt(listenfd_, SOL_SOCKET, SO_REUSEADDR, (char*)&option, sizeof(int)) < 0)
    {
        return -1;
    }
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(sockaddr_in));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(PORT);
    if(bind(listenfd_, (struct sockaddr*)(&server_addr), sizeof(server_addr)) == -1) 
    {
        DEBUG_LOG("bind socket error!n");
        return -1;
    }
    if(listen(listenfd_, 15) == -1) 
    {
        DEBUG_LOG("listen socket error!n");
        return -1;
    }
    
    FD_ZERO(&reads);
    
    FD_SET(listenfd_, &reads);
    
    fd_max = listenfd_;
    return 0;
}

void Network_Interface::select_event(int fd, bool flag)
{
    if(flag)
    {
        
        if(fd_max < fd)
        {
            fd_max = fd;
        }
        
        FD_SET(fd, &reads);
        
        websocket_handler_map_[fd] = new Websocket_Handler(fd);
        
        websocket_ish5run_map_[fd] = true;
        if(fd != listenfd_)
        {
            DEBUG_LOG("fd: %d add select loop", fd);
        }
    }
    else
    {
        
        FD_CLR(fd, &reads);
        
        closesocket(fd);
        
        delete websocket_handler_map_[fd];
        
        websocket_handler_map_.erase(fd);   
        
        websocket_ish5run_map_.erase(fd);
        websocket_ish5configdata_map_.erase(fd);
        websocket_ish5gamedata_map_.erase(fd);
        DEBUG_LOG("fd: %d del select loop", fd);
    }
}

int Network_Interface::select_loop()
{
    
    struct sockaddr_in clnt_adr;
    int fd_num, i, fd = 0, bufflen = 0;
    int clilen = sizeof(SOCKADDR);
    while(true) 
    {
        
        cpy_reads = reads;
        
        if((fd_num = select(fd_max + 1, &cpy_reads, 0, 0,  NULL)) == -1)
            break;
        
        if(fd_num == 0)
            continue;
        
        for(i = 0; i < fd_max + 1; i++)
        {
            
            if(FD_ISSET(i, &cpy_reads))
            {
                
                if(i == listenfd_) 
                {
                    fd = accept(listenfd_, (struct sockaddr*)&clnt_adr, &clilen);   
                    select_event(fd, true);
                }
                else
                {
                    
                    Websocket_Handler* handler = websocket_handler_map_[i];
                    if(handler == NULL)
                    {
                        continue;
                    }
                    
                    if((bufflen = recv(i, handler->getbuff(), BUFFLEN, 0)) == 0)
                    {
                        
                        select_event(i, false);
                    }
                    
                    else if(bufflen == 8)
                    {
                        continue;
                    }
                    else if(bufflen < 0)
                    {
                        break;
                    }
                    else
                    {
                        handler->process();
                    }
                }
            }
        }
    }
    return 0;
}

//

#ifndef __WEBSOCKET_HANDLER__
#define __WEBSOCKET_HANDLER__
#include 
#include 
#include 
#include 
#include "base64.h"
#include "sha1.h"
#include "debug_log.h"
#include "websocket_request.h"

#define MAGIC_KEY "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"

enum WEBSOCKET_STATUS 
{
    WEBSOCKET_UNConNECT = 0,
    WEBSOCKET_HANDSHARKED = 1,
};
typedef std::map HEADER_MAP;
class Websocket_Handler 
{
public:
    Websocket_Handler(int fd);
    ~Websocket_Handler();
    int process();
    inline char* getbuff();
private:
    int handshark();
    void parse_str(char* request);
    int fetch_http_info();
    int send_data(char* buff);
private:
    Websocket_Request* request_;
    char buff_[2048];
    WEBSOCKET_STATUS status_;
    HEADER_MAP header_map_;
    int fd_;
};
    
inline char* Websocket_Handler::getbuff()
{
    return buff_;
}
#endif

//

#include 
#include "websocket_request.h"
#include "network_interface.h"
#include 

Websocket_Request::Websocket_Request(int fd) : fd_(fd),fin_(), opcode_(), mask_(),
    masking_key_(),
    payload_length_(),
    payload_() 
{
    _M_h5aes.setkey("DlClientPost2019");
}

void Websocket_Request::runconfigdata(char *str, int len, int socket)
{
    char* runconfigdata = new char[len + 1];
    memcpy(runconfigdata, str, len + 1);
    printf("nnrunconfigdata = %sn", str);
}

void Websocket_Request::rungamedata(char* str, int len, int socket)
{
  //。。。。
}

int Websocket_Request::websockettoh5(char *content, int length, int fd)
{
    
    if(length == 30)
    {
        return 0;
    }
    printf("content = %s,length = %dn", content,length);
    
    char* data = new char[length + 1];
    memcpy(data, content, length + 1);
    printf("data = %s,length = %dn", data, length);
    
    BYTE* de_base64;
    BYTE* de_payload;
    int ret = _M_h5aes.base64_decode((char*)data, &de_base64);
    if(ret > 0)
    {
        ret = _M_h5aes.decrypt(de_base64, ret, &de_payload);
        if(ret > 0)
        {
            de_payload[ret] = 0;
        }
        else
        {
            return 0;
        }
        printf("nnde_payload = %s,ret = %dn", de_payload, ret);
    }
    else
    {
        return 0;
    }
    
    Json::Value command;
    Json::Reader read;
    read.parse((char *)de_payload, (char *)de_payload + ret, command);
    
    std::cout << command <> 7;
    return 0;
}

int Websocket_Request::fetch_opcode(char *msg, int &pos)
{
    opcode_ = msg[pos] & 0x0f;
    pos++;
    return 0;
}

int Websocket_Request::fetch_mask(char *msg, int &pos)
{
    mask_ = (unsigned char)msg[pos] >> 7;
    return 0;
}

int Websocket_Request::fetch_masking_key(char *msg, int &pos)
{
    if(mask_ != 1)
        return 0;
    for(int i = 0; i < 4; i++)
        masking_key_[i] = msg[pos + i];
    pos += 4;
    return 0;
}

int Websocket_Request::fetch_payload_length(char *msg, int &pos)
{
    payload_length_ = msg[pos] & 0x7f;
    pos++;
    if(payload_length_ == 126)
    {
        uint16_t length = 0;
        memcpy(&length, msg + pos, 2);
        pos += 2;
        payload_length_ = ntohs(length);
    }
    else if(payload_length_ == 127)
    {
        uint32_t length = 0;
        memcpy(&length, msg + pos, 4);
        pos += 4;
        payload_length_ = ntohl(length);
    }
    return 0;
}

int Websocket_Request::fetch_payload(char *msg, int &pos)
{
    memset(payload_, 0, sizeof(payload_));
    if(mask_ != 1)
    {
        memcpy(payload_, msg + pos, payload_length_);
    }
    else
    {
        for(int i = 0; i < payload_length_; i++)
        {
            int j = i % 4;
            payload_[i] = msg[pos + i] ^ masking_key_[j];
        }
    }
    pos += payload_length_;
    return 0;
}

void Websocket_Request::print()
{
    DEBUG_LOG("WEBSOCKET PROTOCOLn"
        "FIN: %dn"
        "OPCODE: %dn"
        "MASK: %dn"
        "PAYLOADLEN: %dn"
        "PAYLOAD: %s",
        fin_, opcode_, mask_, payload_length_, payload_);
    reset();
}

//

#ifndef __WEBSOCKET_REQUEST__
#define __WEBSOCKET_REQUEST__

#include 
#include "debug_log.h"
#include 
class Websocket_Request 
{
public:
    Websocket_Request() {};
    Websocket_Request(int fd);
    ~Websocket_Request() {};
    int fetch_websocket_info(char *msg);
    void runconfigdata(char* str, int len, int socket);
    void rungamedata(char* str, int len, int socket);
    void print();
    void reset();
    int websockettoh5(char *content, int length,int fd);
private:
    int fetch_fin(char *msg, int &pos);
    int fetch_opcode(char *msg, int &pos);
    int fetch_mask(char *msg, int &pos);
    int fetch_masking_key(char *msg, int &pos);
    int fetch_payload_length(char *msg, int &pos);
    int fetch_payload(char *msg, int &pos);
private:
    DL_AES               _M_h5aes;
    uint8_t fin_;
    uint8_t opcode_;
    uint8_t mask_;
    uint8_t masking_key_[4];
    uint64_t payload_length_;
    char payload_[2048];
    int fd_;
};

#endif

//以下这个类的话,主要用来回复客户端。

#include "websocket_respond.h"
#include "websocket_handler.h"
#include 

void Websocket_Respond::respondClient(int sockClient, int state, int type, int info, bool finalFragment)
{
    Json::Value  _M_reply;
    _M_reply["state"] = state;
    _M_reply["gcode"] = type;
    if (info == 1)
    {
        _M_reply["type"] = "configData";
    }
    else if(info == 2)
    {
        _M_reply["type"] = "gameData";
    }
    Json::FastWriter fast;
    std::string str = fast.write(_M_reply);
    
    DL_AES dlaes;
    dlaes.setkey((const char*)"DlClientPost2019");
    unsigned char* _ect;
    char* _base64;
    int len = dlaes.encrypt((unsigned char*)str.c_str(), str.length(),&_ect);
    int length = dlaes.base64_encode(_ect, len, &_base64);
    
    int realDateLength = 0;
    if(length < 126)
    {
        realDateLength = length + 2;
    }
    else if(length < 65536) 
    {
        realDateLength = length + 4;
    }
    else
    {
        realDateLength = length + 10;
    }
    unsigned char* buf = (unsigned char*)malloc(realDateLength);;
    char* charbuf = (char*)malloc(realDateLength);
    int first = 0x00;
    int tmp = 0;
    if(finalFragment) 
    {
        //数据一次性发送完毕
        first = first + 0x80;
        first = first + 0x1;
    }
    buf[0] = first;
    tmp = 1;
    unsigned int nuNum = (unsigned)length;
    if(length < 126) 
    {
        buf[1] = length;
        tmp = 2;
    }
    else if (length < 65536)
    {
        buf[1] = 126;
        buf[2] = nuNum >> 8;
        buf[3] = length & 0xFF;
        tmp = 4;
    }
    else
    {
        //数据长度超过65536
        buf[1] = 127;
        buf[2] = 0;
        buf[3] = 0;
        buf[4] = 0;
        buf[5] = 0;
        buf[6] = nuNum >> 24;
        buf[7] = nuNum >> 16;
        buf[8] = nuNum >> 8;
        buf[9] = nuNum & 0xFF;
        tmp = 10;
    }
    for(int i = 0; i < length; i++)
    {
        buf[tmp + i] = _base64[i];
    }
    memcpy(charbuf, buf, realDateLength);
    
    send(sockClient, charbuf, realDateLength, 0);
}

//

#ifndef __WEBSOCKET_RESPOND__
#define __WEBSOCKET_RESPOND__
class Websocket_Respond 
{
public:
    Websocket_Respond() {};
    ~Websocket_Respond() {};
public:
    void respondClient(int sockClient, int state, int type, int info, bool finalFragment);
};
#endif
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/303145.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号