【问题标题】:C++ - Unable to get prefixed uint16_t headerC++ - 无法获取前缀 uint16_t 标头
【发布时间】:2020-10-20 09:41:58
【问题描述】:

以下是我如何使用 FlatBuffers 构建消息以及如何通过 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] = (opc&0xFF);
memcpy(actualBuffer + 2, buf, size);


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

所以我基本上想要实现的是在 flatbuffers 消息前面添加一个 uint16_t 标头。

这是我使用的结构。

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(&_packet.header_buffer, &_packet.header_buffer[0], sizeof (_packet.headerCode));
            std::cout << "Header Code: " << _packet.headerCode << std::endl;
            //read_size();
        }
    });
}

不幸的是,这给了我以下输出:

Header Code: 0

为什么以及如何正确获取前置的 2 字节标头?我的错误在哪里,我该如何解决?

【问题讨论】:

  • 有什么特别的原因,你为什么要为一个固定的数据字段声明一个向量?为什么不写uint8_t header_buffer[2];除此之外,我对 Boost 没有任何经验,但是在网络方面,我倾向于建议首先查看 Wireshark 捕获的数据,看看您期望的数据是否真的被发送.
  • 哦,你正在从 header_buffer 复制到 header_buffer。您可能希望将其更改为 std::memcpy(&amp;_packet.headerCode, &amp;_packet.header_buffer[0], sizeof (_packet.headerCode));
  • 是的,就是@RefugnicEternium。请回答,以便我接受。
  • 我已经准备好了,但是电话响了。 :)
  • 回答为什么我使用调整向量的大小是因为它是std::vector&lt;std::byte&gt; header_buffer;

标签: c++


【解决方案1】:

您的“复制步骤”中有一个错误,您正在从源复制到目标。 (编译器实际上可能会通知您)。

如果您将 memcpy 更改为 std::memcpy(&amp;_packet.headerCode, &amp;_packet.header_buffer[0], sizeof (_packet.headerCode));,它应该会开始工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    相关资源
    最近更新 更多