2011-05-31 1 views
-2
bool Connection::Receive(){ 
    std::vector<uint8_t> buf(1000); 
    boost::asio::async_read(socket_,boost::asio::buffer(buf,1000), 
      boost::bind(&Connection::handler, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); 

    int rcvlen=buf.size(); 
    ByteBuffer b((std::shared_ptr<uint8_t>)buf.data(),rcvlen); 
    if(rcvlen <= 0){ 
     buf.clear(); 
     return false; 
    } 
    OnReceived(b); 
    buf.clear(); 
    return true; 
} 

La méthode fonctionne bien mais seulement quand je fais un point d'arrêt à l'intérieur. Y a-t-il un problème de synchronisation en attente de réception? Sans le point d'arrêt, rien n'est reçu.Est-ce que je reçois une condition de course avec mon boost asio async_read?

+0

Je ne comprends pas votre question. Essayez d'utiliser ',' ou '.' par exemple ... – nabulke

+0

@nabulke vérifier maintenant – Abanoub

+5

Veuillez ne pas utiliser d'argot. "si bizarre" n'est pas une question, et "w8ting" n'est pas un mot réel. Ce n'est pas un forum. – Soviut

Répondre

4

Vous essayez de lire à partir du tampon de réception immédiatement après le démarrage de l'opération asynchrone, sans attendre qu'il se termine, c'est pourquoi il fonctionne lorsque vous définissez un point d'arrêt.

Le code après votre async_read appartient à Connection::handler, puisqu'il s'agit du rappel que vous avez demandé à async_read d'invoquer après avoir reçu des données.

Qu'est-ce que vous voulez habituellement est un start_read et une fonction handle_read_some:

void connection::start_read() 
{ 
    socket_->async_read_some(boost::asio::buffer(read_buffer_), 
     boost::bind(&connection::handle_read_some, shared_from_this(), 
      boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 
} 

void connection::handle_read_some(const boost::system::error_code& error, size_t bytes_transferred) 
{ 
    if (!error) 
    { 
     // Use the data here! 

     start_read(); 
    } 
} 

Notez les shared_from_this, il est important si vous voulez que la durée de vie de votre connexion à prendre automatiquement en charge par le nombre de I en circulation/O demandes. Assurez-vous de dériver votre classe de boost::enable_shared_from_this<connection> et de la créer uniquement avec make_shared<connection>.

Pour appliquer cela, votre constructeur devrait être privé et vous pouvez ajouter une déclaration d'ami (version C++ 0x, si votre compilateur ne supporte pas cela, vous devrez insérer le nombre correct d'arguments vous-même):

template<typename T, typename... Arg> friend boost::shared_ptr<T> boost::make_shared(const Arg&...); 

Assurez-vous également que votre tampon de réception est toujours actif au moment où le rappel est appelé, de préférence en utilisant une variable de membre de mémoire tampon de taille statique de votre classe de connexion.

+0

@xDD il me donne cette erreur 'tr1 :: bad_weak_ptr' – Abanoub

+0

Assurez-vous que vous n'utilisez pas' shared_from_this() 'dans le constructeur, car tout n'est pas configuré à ce moment-là. Vous pouvez créer une fonction d'assistance statique publique qui crée une connexion en utilisant 'make_shared', puis appelle' start_read() '. – xDD

+0

@xDD regarder j'ai trois classes les vérifier u comprendre ce que je tente de faire Connection http://pastebin.com/zWQHVgSp ConnectionFactory http://pastebin.com/fyx4eZdZ serveur http: //pastebin.com/3DAcH7Db Je ne sais pas comment le faire fonctionner comme vous me dites:/ – Abanoub

Questions connexes