2017-10-02 7 views
0

J'encapsule le socket boost-asio, mais j'ai un problème avec celui-ci, mais ni async_read ni async_write n'appellent leur fonction de rappel et je ne comprends pas pourquoi.Boost asio, async_read et acync_write ne pas appeler les callbacks

J'ai essayé d'utiliser async_read_some mais j'avais le même problème.

Voici le code que j'ai écrit jusqu'à présent

#include <iostream> 
#include "socket.hpp" 

Socket::Socket() 
{ 
    boost::asio::ip::tcp::endpoint ep_tmp(boost::asio::ip::tcp::v4(), 4242); 

    endpoint = ep_tmp; 
    acceptor = new boost::asio::ip::tcp::acceptor(ios, endpoint); 
    tcp_socket = new boost::asio::ip::tcp::socket(ios); 
    acceptor->listen(); 
} 

Socket::~Socket() 
{ 
    delete(acceptor); 
    delete(tcp_socket); 
} 

void  Socket::get_connection() 
{ 
    acceptor->async_accept(*tcp_socket, [](const boost::system::error_code &ec) 
      { 
       std::cout << "Connection received." << std::endl; 
       if (ec) 
       std::cout << "Error " << ec << std::endl; 
      }); 
    this->exec(); 
} 

void  Socket::send(std::string &message) 
{ 
    async_write(*tcp_socket, boost::asio::buffer(message), 
      [](const boost::system::error_code &ec, 
     std::size_t bytes_transferred) 
      { 
     std::cout << "Sending datas." << std::endl; 
     if (ec) 
      std::cout << "Error " << ec << std::endl; 
     else 
      std::cout << bytes_transferred << " bytes transferred." << std::endl; 
      }); 
} 

void  Socket::receive(void) 
{ 
    char  *buf; 

    buf = (char *)malloc(sizeof(char) * 50); 
    buf = (char *)memset(buf, 0, 50); 
    async_read(*tcp_socket, boost::asio::buffer(buf, 50), 
     [](const boost::system::error_code &ec, 
     std::size_t bytes_transferred) 
     { 
      std::cout << "Receiving datas." << std::endl; 
      if (ec) 
     std::cout << "Error " << ec << std::endl; 
      else 
     std::cout << bytes_transferred 
       << " bytes transferred." << std::endl; 
     }); 
} 

void  Socket::exec(void) 
{ 
    ios.run(); 
} 

int  main() 
{ 
    Socket serv; 
    std::string data_test; 

    data_test = "Test\n"; 
    serv.get_connection(); 
    serv.send(data_test); 
    serv.exec(); 
    serv.receive(); 
    serv.exec(); 
    return (0); 
} 

Le bit malloc est temporaire jusqu'à ce que je trouve un moyen de le faire sans utiliser C.

je serais très reconnaissant si quelqu'un pouvait éclaire moi sur cette question

Répondre

0

Je suis avec yuri: je préfère ne pas être asynchrone à moins de savoir ce que vous faites.

Il pourrait ressembler à ceci: http://coliru.stacked-crooked.com/a/523a7828a9aee4b2

#include <boost/asio.hpp> 
#include <iostream> 

namespace ba = boost::asio; 
using ba::ip::tcp; 

class Socket { 
    public: 
    Socket() { acceptor.listen(); } 

    void get_connection(); 
    void exec(); 
    void send(std::string const &message); 
    void receive(void); 

    private: 
    ba::io_service ios; 
    tcp::endpoint endpoint{ tcp::v4(), 4242 }; 
    tcp::acceptor acceptor{ ios, endpoint }; 
    tcp::socket tcp_socket{ ios }; 
}; 

void Socket::get_connection() { 
    acceptor.accept(tcp_socket); 
    std::cout << "Connection received.\n"; 
} 

void Socket::send(std::string const &message) { 
    std::cout << "Sending datas.\n"; 
    auto bytes_transferred = ba::write(tcp_socket, ba::buffer(message)); 
    std::cout << bytes_transferred << " bytes transferred.\n"; 
} 

void Socket::receive(void) { 
    std::cout << "Receiving datas.\n"; 

    char buf[50] = { 0 }; 
    auto bytes_transferred = ba::read(tcp_socket, ba::buffer(buf)); 
    std::cout << bytes_transferred << " bytes transferred.\n"; 
} 

int main() { 
    Socket serv; 

    serv.get_connection(); 
    serv.send("Test\n"); 
    serv.receive(); 
} 

Si vous voulez comportement async, vous devez gérer la durée de vie de chaque tampon/ressource spécifique à la connexion. Il y a beaucoup d'exemples de cela, par ex. dans la documentation ou ici: http://coliru.stacked-crooked.com/a/95e2000e49b4db1d

1

Vous devez appeler io_service::reset avant le deuxième et plus tard appelle io_service::run. Et vous voudrez probablement utiliser l'API synchrone à la place, car votre approche actuelle va complètement à l'encontre de l'objectif de l'asynchronicité.