【问题标题】:How can I wrap std::wstring in boost::asio::buffer?如何将 std::wstring 包装在 boost::asio::buffer 中?
【发布时间】:2011-04-05 16:56:02
【问题描述】:

我正在使用 boost::asio 编写客户端服务器应用程序。我想将结构从客户端传输到服务器。该结构中有一些 std::wstrings。如何对 boost::asio::buffer 中的结构进行编码?

【问题讨论】:

    标签: c++ serialization boost-asio


    【解决方案1】:

    我通常使用boost::asio::streambuf 来序列化结构。

    Message.h

    #ifndef MESSAGE_H
    #define MESSAGE_H
    
    #include <boost/serialization/string.hpp>
    
    #include <string>
    
    struct Message
    {
        std::string _a;
        std::string _b;
    
        template <class Archive>
        void serialize(
                Archive& ar,
                unsigned int version
                )
        {
            ar & _a;
            ar & _b;
        }
    };
    
    #endif
    

    client.cpp

    #include "Message.h"
    
    #include <boost/archive/text_oarchive.hpp>
    
    #include <boost/asio.hpp>
    
    int
    main()
    {
        Message msg;
        msg._a = "hello";
        msg._b = "world";
    
        boost::asio::streambuf buf;
        std::ostream os( &buf );
        boost::archive::text_oarchive ar( os );
        ar & msg;
    
        boost::asio::io_service io_service;
        boost::asio::ip::tcp::socket socket( io_service );
        const short port = 1234;
        socket.connect(
                boost::asio::ip::tcp::endpoint(
                    boost::asio::ip::address::from_string( "127.0.0.1" ),
                    port
                    )
                );
    
        const size_t header = buf.size();
        std::cout << "buffer size " << header << " bytes" << std::endl;
    
        // send header and buffer using scatter
        std::vector<boost::asio::const_buffer> buffers;
        buffers.push_back( boost::asio::buffer(&header, sizeof(header)) );
        buffers.push_back( buf.data() );
        const size_t rc = boost::asio::write(
                socket,
                buffers
                );
        std::cout << "wrote " << rc << " bytes" << std::endl;;
    }
    

    server.cpp

    #include "Message.h"
    
    #include <boost/archive/text_iarchive.hpp>
    
    #include <boost/asio.hpp>
    
    int
    main()
    {
        boost::asio::io_service io_service;
        const uint16_t port = 1234;
        boost::asio::ip::tcp::acceptor acceptor(
                io_service,
                boost::asio::ip::tcp::endpoint(
                    boost::asio::ip::address::from_string( "127.0.0.1" ),
                    port
                    )
                );
    
        boost::asio::ip::tcp::socket socket( io_service );
        acceptor.accept( socket );
        std::cout << "connection from " << socket.remote_endpoint() << std::endl;
    
        // read header
        size_t header;
        boost::asio::read(
                socket,
                boost::asio::buffer( &header, sizeof(header) )
                );
        std::cout << "body is " << header << " bytes" << std::endl;
    
        // read body
        boost::asio::streambuf buf;
        const size_t rc = boost::asio::read(
                socket,
                buf.prepare( header )
                );
        buf.commit( header );
        std::cout << "read " << rc << " bytes" << std::endl;
    
        // deserialize
        std::istream is( &buf );
        boost::archive::text_iarchive ar( is );
        Message msg;
        ar & msg;
    
        std::cout << msg._a << std::endl;
        std::cout << msg._b << std::endl;
    }
    

    【讨论】:

    • 我认为这可以很好地发送数据。这也适用于从套接字读取数据吗?这里我们事先并不知道传入字符串的大小。
    • 是的,您需要发送一个固定长度的标头来指示缓冲区的大小。
    • 如果您还更新使用标头信息读取流的代码会很有帮助
    • 我添加了一个服务器示例,展示如何接收标头和正文
    • 在服务器示例的最后,是否定义了两个同名的变量msg?这段代码能编译吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-07
    • 2018-05-21
    相关资源
    最近更新 更多