C — невозможно получить заголовок uint16_t с префиксом

#c

#c

Вопрос:

Вот как я формирую свое сообщение с помощью плоских буферов и как я отправляю его через Boost ASIO.

 enum ServerOpcode : uint16_t{
    SMSG_AUTH_CONNECTION_RESPONSE                    = 0x001,
    SMSG_LOGIN_REQUEST                               = 0x002,
    SMSG_LOGIN_REQUEST_RESPONSE_TEST                 = 0xA99,
};

ServerOpcode opc;
opc = ServerOpcode::SMSG_LOGIN_REQUEST_RESPONSE_TEST;

flatbuffers::FlatBufferBuilder builder;
auto email = builder.CreateString("test@abv.bg");
auto password = builder.CreateString("passHerepassHerepassHerepassHereZzpa");
auto loginRequest = Vibranium::CreateLoginRequest(builder,email,password);
builder.FinishSizePrefixed(loginRequest);
size_t size = builder.GetSize();
uint8_t *buf = builder.GetBufferPointer();

uint8_t *actualBuffer = new uint8_t[size   2];
actualBuffer[1] = (opc >> 8);
actualBuffer[0] = (opcamp;0xFF);
memcpy(actualBuffer   2, buf, size);


boost::asio::write(s, boost::asio::buffer(actualBuffer,size   2));
  

Итак, чего я в основном хочу добиться, так это добавить заголовок uint16_t перед сообщением flatbuffers.

Вот структура, которую я использую.

 class Packet {
public:
    Packet()
    {
    }
    static const int header_size = 2;
    static const int body_size_in_bytes = 4;
    std::vector<std::byte> header_buffer;
    std::vector<std::byte> size_buffer;
    uint16_t headerCode{0};
    uint32_t body_size{0};
    std::vector<std::byte> body_buffer;
    void PreparePacket(ServerOpcode serverOpcode, std::string message);
};
  

И вот как я пытаюсь прочитать заголовок на стороне сервера:

 void Vibranium::Client::read_header() {
    auto self(shared_from_this());
    _packet.header_buffer.resize(_packet.header_size);
    boost::asio::async_read(socket,
    boost::asio::buffer(_packet.header_buffer.data(), _packet.header_size),
    [this, self](boost::system::error_code ec,std::size_t bytes_transferred)
    {
        if ((boost::asio::error::eof == ec) || (boost::asio::error::connection_reset == ec))
        {
            Disconnect();
        }
        else
        {
            std::memcpy(amp;_packet.header_buffer, amp;_packet.header_buffer[0], sizeof (_packet.headerCode));
            std::cout << "Header Code: " << _packet.headerCode << std::endl;
            //read_size();
        }
    });
}
  

К сожалению, это дает мне вывод:

 Header Code: 0
  

Почему и как я могу правильно получить заголовок с добавлением 2 байта? В чем моя ошибка и как я могу ее исправить?

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

1. Есть ли какая-либо конкретная причина, по которой вы бы объявили вектор для фиксированного поля с данными? Почему бы не написать uint8_t header_buffer[2]; что-то другое, у меня нет никакого опыта работы с Boost, однако, когда дело доходит до работы в сети, я склонен предлагать сначала просмотреть данные, полученные Wireshark, чтобы узнать, действительно ли отправляются данные, которые вы ожидаете.

2. О, и вы копируете из header_buffer в header_buffer. Возможно, вы захотите изменить это на std::memcpy(amp;_packet.headerCode, amp;_packet.header_buffer[0], sizeof (_packet.headerCode));

3. Да, это было так @refugeniceternium. Пожалуйста, дайте ответ, чтобы я мог его принять.

4. Я уже был на нем, но потом зазвонил телефон. 🙂

5. Чтобы ответить, почему я использую изменение размера вектора, это потому, что это std::vector<std::byte> header_buffer;

Ответ №1:

В вашем «шаге копирования» ошибка, вы копируете из источника в цель. (Компилятор может фактически уведомить вас об этом).

Если вы измените свой memcpy на std::memcpy(amp;_packet.headerCode, amp;_packet.header_buffer[0], sizeof (_packet.headerCode)); , он должен начать работать.