C'est quoi le type de m_networkBuffer ?
(Au passage tu as bien un buffer de réception par client ?)
C'est voulu si tu ne donnes pas la taille des données attendues en faisant le async_read ?
MAT.
C'est quoi le type de m_networkBuffer ?
(Au passage tu as bien un buffer de réception par client ?)
C'est voulu si tu ne donnes pas la taille des données attendues en faisant le async_read ?
MAT.
Désolé pour le délai, j'ai eu des soucis de courant et de téléphone depuis samedi, récupérés ce matin.
m_networkBuffer est un std::vector<char>, j'en ai bien un par client. Cependant, je ne comprends pas trop ce que tu entends par la taille des données attendues ?
Si tu veux jeter un oeil, je risque de pas être trop présent dans les quelques jours qui viennent, la source est dispo ici : http://code.google.com/p/mgep/source/browse/trunk/ (Serveur/CommunicationClients et Client/CommunicationServeur)
À la prochaine,
Marc
Lors de la construction du asio::buffer tu utilises cette primitive.
Comme ton vecteur est vide, ça fait un buffer vide et ça explique qu'il soit considéré comme "prêt" tout de suite, d'où déclenchement de la callback tout de suite, etc...
En général on commence par lire l'entête du message (d'une certaine taille fixe connue à l'avance donc) qui contient la taille des données à lire ensuite.
C'est d'ailleurs ce qui est fait dans l'exemple du serveur de chat.
MAT.
Ok, je vois le problème... Il y a un moyen de considérer le buffer comme prêt uniquement si il contient plus de X octets ?
Je ne crois pas non, juste lorsque le buffer contient exactement X octets.
Ça ne serait pas très pratique de savoir qu'il contient au moins X octets puisqu'il faudra de toute façon un moyen de tester si tout est là avant de pouvoir en faire quelque chose.
MAT.
Ben, je voudrais uniquement tester que le buffer ne soit pas vide, pour éviter l'appel en boucle justement. Sinon, je ne vois pas trop comment faire...
C'est normal que ça boucle, il faut bien recommencer à lire après avoir reçu et traité un message.
Tu fais un premier async_read avec comme taille de buffer par exemple sizeof( std::size_t ) dans lequel tu lis la taille du message à venir dans une première callback.
Puis tu fais un autre async_read avec comme taille de buffer la taille que tu viens de lire dans l'entête pour recevoir le contenu utile du message dans une seconde callback.
Ensuite tu traites ton message et une fois que c'est fait tu te remets en attente de lecture d'un nouvel entête en rappelant le premier async_read.
Bien sûr de l'autre côté lors de l'envoi il faut que tu commences par écrire la taille du message (un std::size_t donc) puis ensuite le contenu utile du message.
C'est fait comme ça dans l'exemple d'ailleurs si je ne m'abuse.
MAT.
Ok, côté client, j'envoie ça en un seul paquet avec un caractère de séparation ou une taille précise pour l'entête, ou en deux paquets séparés ?
Edit : j'ai fait un petit test en remplissant le buffer avant d'appeller async_read... En effet la fonction n'est plus appelée en boucle, mais à chaque fois qu'elle est appelée, elle ne contient pas ce qui a été reçu, mais ce avec quoi j'ai rempli le buffer au début... Alors que ça devrait avoir été remplacé, non ? J'ai essayé de mettre un m_networkBuffer.clear(), mais rien à faire, je "reçois" toujours le même caractère... Je commence à désespérer :/
Re edit : visiblement, j'ai (un peu) moins de soucis avec un boost::array<1024, char>, et je viens de m'appercevoir que c'est aussi ce que j'utilise pour le client, je vais me pencher là dessus... Pas mal de segfaults dont je sais pas d'où elles viennent, mais ça va aller :/
Bon, ben voilà, résolu avec un boost::array<1024, char> comme m_networkBuffer. Voilà ma fonction de réception, au final :
Voili voilà, merci pour l'aide encore une fois
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 void NetworkMachine::tcpAsyncReceive(const boost::system::error_code& pE, size_t pBytesReceived) { if (pE.value() != 0) { // Erreur, on déconnecte le client } // Le message a bien été reçu if (pBytesReceived > 0) { // On le traite } // Et on remet le socket en écoute m_tcpSocket->async_receive(boost::asio::buffer(m_networkBuffer), boost::bind(&NetworkMachine::tcpAsyncReceive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); }
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager