alternatives à std:: chaîne à utiliser avec boost:: asio

boost::asiodivers read et write les fonctions et les méthodes accepter boost::asio::buffer. Selon documentation du buffer, un mutable std::string ne peut pas être enveloppé dans boost::asio::buffer, et ne peut donc pas être utilisé pour asio read fonctions. Ceci est probablement dû au fait que std::string ne permet pas l'accès mutable à son tampon interne (ceci a été discuté précédemment ici).

C'est une honte, parce que std::string est une façon commode de représenter des tampons de données mutables en C++. Sans elle, il ne nous reste plus que des tableaux de POD,boost::array et std::vector<char>. Les deux premiers sont peu commodes avec des messages de longueur variable. std::vector<char> peut fonctionner, mais c'est de façon naturelle à porter des tampons de données (*)

Questions:

  1. y a-t-il d'autres alternatives à std::stringboost::asio pour la lecture des tampons? Suis-je manqué quelque chose?
  2. je me demande pourquoi std::vector<char> pris en charge dans un mutable tampon. Est-ce parce qu'il garantit la mémoire tampon interne est contiguë en mémoire et permet mutable accès avec &vec[0]?

Merci d'avance


(*) à mon humble avis. Regardez protobuf la sérialisation par exemple -, il propose de sérialisation dans std::string mais pas std::vector<char>, du moins pas explicitement.


EDIT: j'ai fini par utiliser vector<char> après tout. protobuf permet la sérialisation dans un vector<char> par le SerializeToArray appel qui prend un pointeur (&vec[0] peut y être passé).

19
demandé sur Community 2011-03-09 18:49:24

3 réponses

C'est pour répondre à Eli commentaire

je n'ai pas mentionné asio::streambuf dans mon question à l'origine, en effet parce qu'il n'est pas 100% clair pour moi comment l'utiliser avec des tailles fixes lit et asio. Pourrait vous pointez vers un exemple (ou en ajouter un comme une réponse) de montrer comment lire des morceaux de longueur fixe en std::sstream?

Ici une réponse précédente sur l'utilisation de asio::streambuf et Boost.Serialization. Asio documentation aussi a un exemple de lecture synchrone:

boost::asio::streambuf b;

// reserve 512 bytes in output sequence
boost::asio::streambuf::mutable_buffers_type bufs = b.prepare(512);

size_t n = sock.receive(bufs);

// received data is "committed" from output sequence to input sequence
b.commit(n);

std::istream is(&b);
std::string s;
is >> s;
5
répondu Sam Miller 2017-05-23 12:34:32

accès Mutable à un tampon de chaîne en utilisant &str[0] fonctionne très bien sur toutes les implémentations connues, et la formulation du prochain standard C++0x le rend officiellement autorisé.

pourtant, je pense que vous êtes fou de penser que a std::vector est une représentation non naturelle pour un tampon de longueur variable.

8
répondu Ben Voigt 2011-03-10 05:08:25

1) des alternatives peuvent être trouvées en cochant asio::buffer() fonction, les surcharges qui retour mutable_buffers_1. l'option plus flexible (mais probablement sous-optimale) est asio::streambuf utile (async_)read_until.

si vous avez le protocole des champs de taille fixe, vous pouvez utiliser le tableau de asio::mutable_buffer. par exemple,

using boost::asio;
int i;
short s;
char data[data_size]; // data_size is defined elsewhere
boost::array<asio::mutable_buffer, 3> bufs = {
    asio::buffer(&i, 4), 
    asio::buffer(&s, 2),
    asio::buffer(data, data_size)
};
asio::read(socket, buffer(bufs)); // socket defined elsewhere

2) vous avez déjà fait référence grande réponse à cette question:"Comment lire de manière asynchrone à std::string à l'aide de Boost::asio?"

2
répondu Andriy Tylychko 2017-05-23 11:54:44