2009-08-24 16 views
0

J'ai fait une application socket qui utilise boost asio mais il semble que ça prend beaucoup de cpu quand j'essaye de lire n'importe quoi depuis la socket.boost asio prenant 100% cpu à lire

Atm i utiliser une classe wrapper donc je n'ai pas pour afficher les fichiers d'en-tête de coup de pouce dans mon fichier d'en-tête qui ressemble à ceci:

class SocketHandle 
{ 
public: 
    SocketHandle() 
    { 
     m_pSocket = NULL; 
     m_pService = NULL; 
    } 

    ~SocketHandle() 
    { 
     delete m_pSocket; 
     delete m_pService; 
    } 

    void connect(const char* host, const char* port) 
    { 
     if (m_pSocket || m_pService) 
      return; 

     m_pService = new boost::asio::io_service(); 

     tcp::resolver resolver(*m_pService); 
     tcp::resolver::query query(tcp::v4(), host, port); 
     tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); 
     tcp::resolver::iterator end; 

     m_pSocket = new tcp::socket(*m_pService); 

     boost::system::error_code error = boost::asio::error::host_not_found; 

     while (error && endpoint_iterator != end) 
     { 
      (*m_pSocket).close(); 
      (*m_pSocket).connect(*endpoint_iterator++, error); 
     } 

     if (error) 
      throw ... 
    } 

    tcp::socket* operator->() 
    { 
     return m_pSocket; 
    } 

private: 
    tcp::socket *m_pSocket; 
    boost::asio::io_service *m_pService; 
}; 

puis lecture im de la prise comme ceci:

size_t recv(char *data, size_t size) 
{ 
    boost::system::error_code error; 
    size_t len = (*m_pSocket)->read_some(boost::asio::buffer(data, size), error); 

    if (error) 
       throw ... 

    return len; 
} 

Est-ce que je fais quelque chose de mal? Y a-t-il une meilleure façon de lire les données de la socket?

Boost 1.39.0 visual C++ windows

Répondre

0

Vous devez éviter la serré en boucle:

// BAD. 
while (error && endpoint_iterator != end) 
{ 
    (*m_pSocket).close(); 
    (*m_pSocket).connect(*endpoint_iterator++, error); 
} 

plutôt essayer quelque chose comme:

try 
{ 
    (*m_pSocket).connect(*endpoint_iterator++, error); 
    // ... 
} 
catch (std::exception& ex) 
{ 
    // Release resources, then try connecting again. 
} 

Voir également examples à des les bons idiomes d'utiliser Asio.

+0

C'était à partir de l'exemple de boost asio: P – Lodle

+0

Mais le problème est avec le lire pas le code de connexion. – Lodle

0

la place Pensez à utiliser sans fonction,

size_t len = asio::read(*m_pSocket,asio::buffer(data, size), error); 
+0

pourquoi? Y a-t-il une différence? –

1

Un changement que vous pouvez envisager (et je recommande fortement) est de rendre votre prise des appels asynchrones. De cette façon, vous n'avez pas à vous soucier du blocage des threads ou des appels de socket en interne (ce que je soupçonne être ce que vous voyez). Au lieu de cela, vous fournissez simplement un rappel qui recevra les erreurs et le nombre d'octets reçus. Les documents Boost illustrent comment faire ceci, et j'ai constaté qu'il se prête à une utilisation beaucoup plus efficace des threads et des ressources du processeur.

Questions connexes