2011-05-20 3 views
2

Je tente de convertir la valeur de retour de la fonction boost::asio::async_read à un int afin de voir si j'ai reçu des données:Retourne le nombre d'octets lus par boost :: asio :: async_read

int recvlen = boost::asio::async_read (
    socket_, 
    boost::asio::buffer((char*)buffer, 1000), 
    boost::bind(&Connection::Receive, this, boost::asio::placeholders::error) 
); 

Voici cette déclaration dans le contexte du reste de mon code, qui ne compile pas:

.h:

#ifndef _CONNECTION_H_ 
#define _CONNECTION_H_ 

#include <boost/bind.hpp> 
#include <boost/shared_ptr.hpp> 
#include <boost/enable_shared_from_this.hpp> 
#include <boost/asio.hpp> 
#include <stdint.h> 

class Connection 
{ 
public: 
    Connection(boost::asio::io_service& io_service); 
    ~Connection(); 
    boost::asio::ip::tcp::socket& socket() {return socket_;} 
    void Send(uint8_t* buffer, int length); 
    bool Receive(); 

protected: 
    virtual void OnReceived(uint8_t* buffer, int len) = 0; 

private: 
    boost::asio::ip::tcp::socket socket_; 
}; 

#endif 

fichier .cpp:

#include "Connection.h" 

Connection::Connection(boost::asio::io_service& io_service)  
    : socket_(io_service) {} 

Connection::~Connection() {} 

void Connection::Send(uint8_t* buffer,int length) { 
    boost::asio::async_write (
     socket_, 
     boost::asio::buffer(buffer, length), 
     boost::bind(&Connection::Send, this,boost::asio::placeholders::error) 
    ); 
} 

bool Connection::Receive(){ 
    uint8_t* buffer = new uint8_t[1000]; 

    //Conversion excerpt 
    int recvlen = boost::asio::async_read (
     socket_, 
     boost::asio::buffer((char*)buffer, 1000), 
     boost::bind(&Connection::Receive, this, boost::asio::placeholders::error) 
    ); 

    if (recvlen <= 0) { 
     delete[] buffer; 
     return false; 
    } 

    this->OnReceived(buffer, recvlen); 

    delete[] buffer; 

    return true; 
} 

Ce sont les erreurs de ce code produit dans Visual C++:

error C2825: 'F': must be a class or namespace when followed by '::' e:\boost_1_46_1\boost_1_46_1\boost\bind\bind.hpp 69 
error C2039: 'result_type' : is not a member of '`global namespace'' e:\boost_1_46_1\boost_1_46_1\boost\bind\bind.hpp 69 
error C2146: syntax error : missing ';' before identifier 'type' e:\boost_1_46_1\boost_1_46_1\boost\bind\bind.hpp 69 
error C2208: 'boost::_bi::type' : no members defined using this type e:\boost_1_46_1\boost_1_46_1\boost\bind\bind.hpp 69 
error C1903: unable to recover from previous error(s); stopping compilation e:\boost_1_46_1\boost_1_46_1\boost\bind\bind.hpp 69 
IntelliSense: a value of type "void" cannot be used to initialize an entity of type "int" d:\c++\ugs\common\connection.cpp 18 
IntelliSense: the #endif for this directive is missing d:\c++\ugs\common\connection.h 1 
IntelliSense: this declaration has no storage class or type specifier d:\c++\ugs\common\connection.h 26 

Comment puis-je accomplir ce que je suis en train de faire? En outre, que signifient ces erreurs et comment puis-je les corriger?

+0

@Kiril Kirov je ne sais pas non plus quand je double clique cette erreur, il va ici bind.hpp result_traits struct 'modèles { typedef typename F :: type result_type; }; 'mais je n'utilise pas F idk ce qui est faux !!? – Abanoub

+0

désolé, j'ai presque immédiatement supprimé mon commentaire, car j'ai raté certaines choses. Désolé, je ne peux pas vous aider, je n'ai jamais utilisé boost, malheureusement. –

Répondre

2

async_read ne retourne pas le nombre d'octets lus. Il effectue la lecture en arrière-plan, de manière asynchrone. Le nombre d'octets est transmis au gestionnaire d'achèvement. Le gestionnaire d'achèvement est appelé par ASIO lorsque la lecture est terminée. Vous passez le gestionnaire de complétion dans async_read. async_read est un modèle qui accepte tout objet fonction en tant que gestionnaire. Dans votre cas, vous avez passé la sortie de l'instruction bind.

Il existe de bons exemples dans le boost documentation, mais voici deux solutions rapides.

Vous pouvez utiliser la fonction synchrone boost :: asio :: read au lieu de boost :: asio :: async_read.

int recvlen = boost::asio::read(socket_,boost::asio::buffer((char*)buffer, 1000)); 

Ou, vous pouvez ajouter une nouvelle fonction:

void HandleReceive(boost::system::error_code &error, std::size_t recvlen) 
{ 
    if (!error && error != boost::asio::error::message_length) { 
     this->OnReceived(buffer, recvlen); 
     delete [] buffer; 
    } // else ERROR!!! 
} 

Et appelez async_read comme

boost::asio::async_read(socket_,boost::asio::buffer((char*)buffer, 1000), 
      boost::bind(&Connection::HandleReceive, this, 
      boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 

Vous devrez faire buffer une variable de classe pour l'exemple asynchrone pour travailler, mais vous voudrez peut-être trouver une meilleure façon de gérer la mémoire. En outre, vous devrez faire quelque chose pour faire face à des problèmes à vie de la classe Connection. Vérifiez les exemples ASIO pour un exemple mieux développé.

+0

Les appels HandleReceive() + async_read() publiés par @Dan sont justes sur l'argent et sont le bon moyen pour quelqu'un d'obtenir le nombre d'octets transférés depuis l'appel async_read() d'asio. – Sean

Questions connexes