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.
Version imprimable
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:
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)); }