2016-05-22 7 views
0

Ich versuche, UDP-Server auszuführen. Das Problem ist das Blockieren von Aufruf von run() auf io_service. Also entschied ich mich, diese Methode auf anderen Threads mit Boost Bind auszuführen. Im Ergebnis geht die Hauptthread-Ausführung aus dem DictionaryImpl-Konstruktorbereich, aber wenn ich das udp-Paket sende, sagt tcpdump, dass mein Port nicht erreichbar ist. Wenn ich run() rufe auf io_service im Haupt-Thread alles ist in Ordnung. Wo ist das Problem?Wie führe ich io_service in einem anderen Thread aus?

class DictionaryImpl { 
    boost::asio::io_service io; 
    boost::scoped_ptr<boost::thread> thread; 

public: 
    DictionaryImpl() { 
     try { 
      udp_server2 udpReceiver(io); 

      thread.reset(new boost::thread(
        boost::bind(&DictionaryImpl::g, this, std::ref(io)))); 

     } catch (std::exception &e) { 
      std::cerr << "Exception: " << e.what() << "\n"; 
     } 

    } 

    void g(boost::asio::io_service & io){ 
     io.run(); 
    } 

    virtual ~DictionaryImpl() { 
     if (!thread) return; // stopped 
     io.stop(); 
     thread->join(); 
     io.reset(); 
     thread.reset(); 
    } 

}; 






class udp_server2 
{ 
public: 
    udp_server2(boost::asio::io_service& io_service) 
      : socket_(io_service, udp::endpoint(udp::v4(), 13003)) 
    { 
     start_receive(); 
    } 

private: 
    void start_receive() 
    { 
     socket_.async_receive_from(
       boost::asio::buffer(recv_buffer_), remote_endpoint_, 
       boost::bind(&udp_server2::handle_receive, this, 
          boost::asio::placeholders::error, 
          boost::asio::placeholders::bytes_transferred)); 
    } 

    void handle_receive(const boost::system::error_code& error, 
         std::size_t /*bytes_transferred*/) 
    { 
     if (!error || error == boost::asio::error::message_size) 
     { 
      std::cout<<"handle_receive\n";  
      start_receive(); 
     } 
    } 



    udp::socket socket_; 
    udp::endpoint remote_endpoint_; 
    boost::array<char, 1> recv_buffer_; 
}; 
+0

posten Sie bitte ein [mcve] –

Antwort

1

DictionaryImpl ‚s io_service stoppt, wenn es aus der Arbeit läuft. Sie können dies unter Verwendung von asio::io_service::work verhindern.

In ~DictionaryImpl rufen Sie reset nach dem Aufruf stop über die io_service. Das einzige Mal, wenn Sie dies tun möchten, ist, wenn Sie die io_service später neu starten möchten.

Es sieht so aus, als würden Sie davon profitieren, die Dokumentation erneut zu lesen (was ich akzeptiere, ist ein wenig spärlich). Sehen Sie sich auch die Multi-Thread-Beispiele in der Asio-Dokumentation an. Sie zeigen Beispiele für die Verwendung eines work Objekts.