Как я могу обернуть std::wstring в boost::asio::buffer?

Я пишу клиент-серверное приложение, используя boost:: asio. Я хочу передать структуру с клиента на сервер. В структуре есть несколько std::wstrings. Как закодировать структуру в boost::asio::buffer?


person Canopus    schedule 30.08.2010    source источник


Ответы (1)


Обычно я использую boost::asio::streambuf для сериализации структур.

Сообщение.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;
}
person Sam Miller    schedule 30.08.2010
comment
Я думаю, что это будет нормально работать с отправкой данных. Это также работает с чтением данных из сокета? Здесь мы заранее не знаем размер входящих строк. - person Canopus; 30.08.2010
comment
да, вам нужно отправить заголовок фиксированной длины, указывающий размер буфера. - person Sam Miller; 30.08.2010
comment
Было бы полезно, если бы вы также обновили код для чтения потока, используя информацию заголовка. - person Canopus; 31.08.2010
comment
Я добавил пример сервера, показывающий, как получить заголовок и тело - person Sam Miller; 31.08.2010
comment
В конце примера с сервером определены ли две переменные с одинаковым именем msg? Этот код компилируется? - person Deqing; 03.07.2016
comment
@Deqing есть единственная переменная с именем msg, код должен скомпилироваться, хотя с тех пор, как я его написал, прошло несколько лет. - person Sam Miller; 05.07.2016
comment
Я понимаю. ar & msg использует оператор &, не определяя ссылку. - person Deqing; 05.07.2016