C++中的boost::asio::buffer和结构体

4
有没有基本上可以这样做的方法:
#include <boost/asio.hpp>

struct testStruct{
    int x;
    int y;
};

int main(){
    struct testStruct t;
    boost::asio::buffer b;
    b = boost::asio::buffer(t); 
    return 0;
}

似乎它在将“t”传递到缓冲区“b”时出现了问题。
3个回答

8

使用scatter操作来处理多个缓冲区:

#include <boost/asio.hpp>

#include <vector>

struct testStruct{
    int x;
    int y;
};

int
main()
{
    struct testStruct t;
    t.x = 5;
    t.y = 7;

    std::vector<boost::asio::const_buffer> buffers;
    buffers.push_back( boost::asio::buffer(&t.x, sizeof(t.x) ) );
    buffers.push_back( boost::asio::buffer(&t.y, sizeof(t.y) ) );

    boost::asio::io_service io_service;
    boost::asio::ip::tcp::socket socket( io_service ); // note not connected!
    std::size_t length = boost::asio::write( socket, buffers );

    return 0;
}

注意,您需要在接收端使用相应的 gather。如果超出了您所提供的人为示例,这将变得非常繁琐。这就是为什么我建议您之前的问题中使用更强大的序列化机制的原因。

没错!这似乎很繁琐...我只是想了解一下我的选择。感谢你一直以来的帮助! - poy
@Andrew 没问题,很高兴能帮助!遇到问题时继续提问,这就是 Stackoverflow 的用途。 - Sam Miller
3
如果需要的话,boost::asio::buffer(&t, sizeof(t)) 更加高效。可以打开或关闭打包功能。 - user405725

3

2

有几件事情你需要小心。

1. 填充

你的结构体布局是与实现相关的。在服务器上,x和y成员之间可能存在占位符字节,而在客户端上则可能不存在。

为了解决这个问题,你应该逐个成员地将结构体序列化到字符缓冲区中,并以相同的方式在客户端上反序列化它们。

你可以编写一些实用程序代码来帮助你完成这个任务,以下是一个起点:

class packet_writer
{
public:
    template <typename iter> void write(iter begin, iter end)
    {
        buffer_.insert(buffer_.end(), begin, end);
    }

    template <typename T> void write(T data)
    {
            int8_t* begin = reinterpret_cast<int8_t*>(&data);
        write(begin, begin + sizeof(data));
    }

    const std::vector<int8_t>& buffer() const
    {
        return buffer_;
    }

private:
    std::vector<int8_t> buffer_;
};

2. 字节序(Endianness)

根据架构或者有时甚至取决于当前CPU模式(一些POWER CPU支持字节序切换),您的成员变量的字节顺序可能会发生反转。您需要检测主机架构的字节序,并将字节交换为预定义的顺序,以便在协议中使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接