将uin32_t写入asio :: streambuf

时间:2017-08-13 03:50:39

标签: c++ c++11 boost boost-asio iostream

我试图将uint32_t写入缓冲区,我将通过网络发送,但我不确定如何正确地执行此操作。最初我假设operator<<会正确处理它并将4个字节写入缓冲区(假设我之前使用过htonl)。相反,我开始获得没有任何意义的价值观。我注意到,当有时向流中写入单个int时,缓冲区的大小有时会增加十个字节而不是预期的四个字节。我写了一个简短的测试,并意识到它实际上将ascii中的整数转储到缓冲区。我想我已经找到了解决方法,但感觉 hacky ,所以我正在寻找一种更好的方式,或者为什么我正在做的事情的理由是右。

这里有一些示例代码:

  boost::asio::streambuf buffer;
  std::ostream os(&buffer);

  uint32_t value = 0x12345678;
  os << value; // Gives ascii 305419896

  os.write((const char *) &value, sizeof(value)); // fives 0x12345678

有没有比我最后一行代码更好的方法呢?

2 个答案:

答案 0 :(得分:1)

你正在做的很好,但 可以直接写给streambuf:

buffer.commit(boost::asio::buffer_copy(
    buffer.prepare(sizeof(value)),
    boost::asio::buffer(&value, sizeof(value))));

答案 1 :(得分:0)

这是通常的做法。如果在两者之间添加一些代码,则可以节省一些时间和代码。

template<class T> void append(T value)
{
    static_assert(std::is_fundamental<T>::value, __FUNCTION__);
    //Convert here to correct endian
    append(reinterpret_cast<const char*>(&value), sizeof(value));
}

template<class T> void append(const T *app, std::size_t size)
{
    return append(reinterpret_cast<const char*>(app), size);
}

void append(const char *s, std::size_t length)
{
    //append to buffer
}

请记住在收到数据时转换为正确的字节序。或者,如果您知道远程机器的预期,请以正确的格式直接发送。

此外,你可以检查这样的字节顺序:

static bool IsBigEndian(void)
{
    union
    {
        uint32_t i;
        char c[4];
    } endi = { 0x01020304 };
    return endi.c[0] == 1;
}