Boost ASIO — как перенести заголовок перед TCP-сообщением

#c #boost-asio

#c #boost-asio

Вопрос:

Вот мой код, свернутый для удобства чтения.

Я следовал этому руководству: https://www.boost.org/doc/libs/1_63_0/doc/html/boost_asio/example/cpp11/chat/chat_server.cpp

Packet.h :

 #ifndef VIBRANIUM_CORE_PACKET_H
#define VIBRANIUM_CORE_PACKET_H


#include <cstdio>
#include <cstdlib>
#include <cstring>

class Packet {
public:
    Packet() : body_length_(0)
    {
    }
    enum { max_body_length = 1024 };
    enum { header_length = 8 };
    char header_[header_length];
    const char* data() const;
    char* data();
    size_t length() const;
    const char* body() const;
    char* body();
    size_t body_length() const;
    void body_length(std::size_t new_length);
    bool decode_header();
    void encode_header();
private:
    char data_[header_length   max_body_length];
    size_t body_length_;
};


#endif //VIBRANIUM_CORE_PACKET_H
  

Packet.cpp :

 #include "Packet.h"

const char *Packet::data() const {
    return data_;
}

char *Packet::data() {
    return data_;
}

size_t Packet::length() const {
    return header_length   body_length_;
}

const char *Packet::body() const {
    return data_   header_length;
}

char *Packet::body() {
    return data_   header_length;
}

size_t Packet::body_length() const {
    return body_length_;
}

void Packet::body_length(std::size_t new_length) {
    body_length_ = new_length;
    if (body_length_ > max_body_length)
        body_length_ = max_body_length;
}

bool Packet::decode_header() {
    char header[header_length   1] = "";
    std::strncat(header, data_, header_length);
    body_length_ = std::atoi(header);
    if (body_length_ > max_body_length)
    {
        body_length_ = 0;
        return false;
    }
    return true;
}

void Packet::encode_header() {
    char header[header_length   1] = "";
    std::sprintf(header, "M", static_cast<int>(body_length_));
    std::memcpy(data_, header, header_length);
}
  

ServerOpcode.h :

 #ifndef VIBRANIUM_CORE_SERVEROPCODE_H
#define VIBRANIUM_CORE_SERVEROPCODE_H

#include <cstdint>

enum ServerOpcode : uint16_t{
    SMSG_AUTH_CONNECTION_RESPONSE                    = 0x001,
    SMSG_LOGIN_REQUEST_RESPONSE                      = 0x002,
};

#endif //VIBRANIUM_CORE_SERVEROPCODE_H
  

Итак, я хотел бы изменить encode_header() , чтобы установить a ServerOpcode в качестве заголовка пакета. Я пытался это сделать, но это не работает:

 void Packet::encode_header(ServerOpcode serverOpcode) {
    char header[header_length   1] = "";
    std::strcat(header, static_cast<char>(serverOpcode));
    std::memcpy(data_, header, header_length);
}
  

У меня есть два вопроса:

  1. Как я могу заставить заголовок encode ServerOpcode предшествовать? Где моя ошибка, как я могу это исправить?
  2. Как я могу декодировать заголовок входящего сообщения, чем с decode_header() помощью?

Комментарии:

1. Я подозреваю, что многие ваши проблемы и большая часть вашей сложности связаны с изобретением новых колес. Вы используете boost asio, но даже не базовый класс, подобный std::string . Вы используете std::sprintf вместо просто std::to_string . std::atoi вместо std::stoi .

2. Я согласен с вами в этом. Не могли бы вы дать ответ с этими изменениями?