alternatives à std:: chaîne à utiliser avec boost:: asio
boost::asio
divers 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:
- y a-t-il d'autres alternatives à
std::string
boost::asio
pour la lecture des tampons? Suis-je manqué quelque chose? - 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é).
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;
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.
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?"