为什么这个简单的Boost :: asio程序不能按预期工作?

问题描述:

我写了这个:为什么这个简单的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()调用之后....

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