2017-06-28 35 views
0

我不得不承认,我有点感到迷惘,很抱歉,如果这个问题心不是很清楚的或微不足道的(其实我希望是后者)....流数据转化为字节数组

我送在网络字节数组,并希望做这样的事情在发送方:

size_t max_size = 100; 
uint8_t buffer[size]; 
idontknowwhat_t x{buffer};  
uint16_t size = 11;     // total number of bytes in the buffer 
uint16_t id_a,id_b,id_c;   // some ids 
uint8_t a,b,c;      // some data 
x << size << id_a << a << id_b << b << id_c << c; 
someMethodToSend(buffer,size); 

,并在接收端是这样的:

size_t max_size = 100; 
uint8_t buffer[size]; 
someMethodToReceive(buffer); 
idontknowwhat_t x{buffer}; 
uint16_t size; 
x >> size; 
for (uint16_t i=0; i<size-2; i++) { 
    uint16_t id; 
    uint8_t data; 
    x >> id >> data; 
    std::cout << id << " " << data; 
} 

所以我的目标是基本上可以避免丑陋的强制转换和手动递增指针,同时能够在缓冲区中有uint8_tuint16_t(也可能有uint32_t)。我在这里放入缓冲区的数据仅仅是一个例子,我知道在通过网络发送时需要注意字节顺序(如果我必须手动执行此操作,那将会很好)。

有什么我可以用来代替我的假设idontknowwhat_t

+0

我认为['boost :: asio :: streambuf'](http://www.boost.org/doc/libs/1_64_0/doc/html/boost_asio/reference/streambuf.html)应该没问题,但我不确定它使用的内部缓冲区是否适合您的用例。 – Rakete1111

+0

@ Rakete1111我想我已经看过它了,但在阅读过很多关于流的不同地方后,我有些困惑。我会试一试,thx的提示 – user463035818

回答

1

你不能真的避免做丑陋的演员,但至少你可以隐藏他们到idontknowwhat_t职业的operator>>operator<<函数。使用模板,您可以将代码中的强制转换次数限制在最低限度。

class idontknowwhat_t 
{ 
    uint8_t* _data; 

public: 
    idontknowwhat_t(uint8_t* buffer) 
     : _data(buffer) 
    {} 

    template<typename insert_type> 
    idontknowwhat_t& operator<<(insert_type value) 
    { 
     *reinterpret_cast<insert_type*>(_data) = value; 
     _data += sizeof(insert_type); 
     return *this; 
    } 
    template<typename extract_type> 
    idontknowwhat_t& operator>>(extract_type& value) 
    { 
     value = *reinterpret_cast<extract_type*>(_data); 
     _data += sizeof(extract_type); 
     return *this; 
    } 
}; 

我认为这将直接与您的代码直接工作。在这个例子中,idontknowwhat_t类不拥有缓冲区,只是保留一个原始指针,指向它期望读取或写入的下一位数据。对于真实的目的,我建议让idontknowwhat_t类管理缓冲存储器。

另外,这个页面上的代码实际上并没有处理数据的字节顺序,这肯定是idontknowwhat_t类的责任。这是一个boost library。我不是在这里记录这个图书馆的用途,因为我认为它分散了真正的问题。

+0

这看起来很好。我非常肯定,我需要所有的boost类,但是我没有设法采用[示例](http://www.boost.org/doc/libs/1_51_0/doc/html/booster_asio/tutorial/tutdaytime4 .html)我找到了我需要的东西。只要接收者事先知道接收它容易的内容,但是如果消息中的类型在消息本身中被编码,那么我就会迷失方向。顺便说一句,这种类型的演员我不认为是丑陋的,因为它只限于几行,并且调用者不会注意到它的存在 – user463035818

+0

Re“只要接收者事先知道接收它的容易,但如果消息中的类型在消息本身编码,我很失落“。这与排列顺序不同。 接收者必须知道它期望的内容 - 至少,它必须告诉'idontknowwhat_t'它希望返回值具有哪种数据类型。你能更具体地说明你想要达到的目标吗? – Kessel

+0

确保注释没有关于字节顺序。我的意思是这些消息不是一个固定的结构,而只是遵循一个固定的协议,例如。 (用例中的问题留)的一定值的'id'可能表明,未来值是'uint32_t'而另一个值可能表示下一个值是'uint16_t' – user463035818

0

你试过std::list?您可以将元素分组成不同的类型,并将它们放入适当类型的列表中。然后你可以创建一个std :: lists的std :: list。

+0

不,我不想在整个网络上发送列表。我想发送一个字节数组,所以我不明白std :: list如何帮助 – user463035818