2009-12-15 62 views
1

我寫了這個:爲什麼這個簡單的Boost :: asio程序不能按預期工作?

#include <vector> 
#include <iostream> 
#include <sstream> 
#include <boost/asio.hpp> 
#include <tr1/memory> 
#include <boost/bind.hpp> 
#include <stdint.h> 

    using namespace boost::asio; 
    using namespace boost::asio::ip; 

class tcpServer{ 
public: 

    class connection{ 

     tcp::socket socketConnection; 

     enum {CONNECTED, CLOSED, CREATED}STATUS; 

    public: 

     uint32_t addr; 
     uint16_t port; 

     connection(boost::asio::io_service &ioServ): socketConnection(ioServ){ 
      STATUS = CREATED; 
     } 

     void setConnected(bool is) { 
      if (is) { 
       STATUS = CONNECTED; 
       port = socketConnection.remote_endpoint().port(); 
       addr 
         = socketConnection.remote_endpoint().address().to_v4().to_ulong(); 
       std::cout << "Connected to " 
         << socketConnection.remote_endpoint().address().to_v4().to_string() 
         << " : " << socketConnection.remote_endpoint().port() 
         << "\n"; 
      } 
     } 

     tcp::socket& getSocket(){ 
      return socketConnection; 
     } 
    }; 

    typedef std::tr1::shared_ptr<tcpServer::connection> CONNSHPTR; 

private: 
    boost::asio::io_service io_service; 
    tcp::acceptor tcpAcceptor; 
    int localPort; 

    void accept(CONNSHPTR connection, const boost::system::error_code& error){ 
     connection->setConnected(true); 
     std::cout.flush(); 
    } 

    void startAccept(){ 
     CONNSHPTR newConn(new connection(tcpAcceptor.io_service())); 

     tcpAcceptor.async_accept(newConn->getSocket(), boost::bind(
         &tcpServer::accept, this, newConn, 
         boost::asio::placeholders::error)); 
    } 

public: 



    tcpServer(int localPort) : 
     io_service(), tcpAcceptor(io_service, tcp::endpoint(tcp::v4(), 
       localPort)) { 
     this->localPort = localPort; 

    } 

    void start(){ 
     io_service.run(); 
     startAccept(); 
    } 
}; 

int main(int argc, char** argv) { 
try{ 
    tcpServer tp(1033); 
    tp.start(); 
}catch(std::exception &e){ 
    std::cout << e.what(); 
} 
    sleep(5000); 
    return 0; 
} 

然後我在終端上就和我寫的telnet本地主機1033的Telnet說我連接,但處理程序不會被調用(GDB不打斷點和COUTS沒有效果)。如果我殺了程序,telnet會說連接已經關閉。所以似乎連接建立了,但爲什麼處理程序不被調用?

編輯:

古怪它的工作原理如果start()方法,我把ioservice.run()後startAccept()。現在,我不知道爲什麼這個作品......其實後來我打電話再次開始接受,它仍然有效,而且它是ioservice.run()調用之後....

回答

5

asio docs

run()函數將阻塞,直到所有工作完成並且沒有更多的處理程序要分派,或者直到io_service已停止。

運行時()之前 startAccept(被稱爲),它會立即返回,因爲它沒有任何關係呢。然後調用startAccept(),它將套接字置於接受模式(所以,當你在你的服務器上進行遠程登錄時,網絡子系統接受它),但run()不會被調用,所以你的接受處理程序永遠不會被調用。

+0

上帝我得使用另一個線程... – gotch4 2009-12-15 19:25:49

+0

不一定。你可以簡單地在完成所有設置後調用run(),或者如果你想交錯其他工作,調度定時器或者調用 poll()或run_one()對io_service – 2009-12-15 20:53:15

相關問題