2011-07-12 37 views
1

操作系统:Linux 64位ARCH。升压ASIO异步接受器不开放侦听端口

BOOST:1.46.1

编译器:铛++/GCC。

我有一个代码片段,具有在boost :: asio示例(Chat Server)上建模的tcp接受器的接线。但是,当我运行该片段时,没有监听TCP套接字出现在netstat监听(linux)中。但是,聊天服务器示例在编译时显示出来。有人能指出我做错了什么吗?

#include <boost/asio.hpp> 
#include <boost/shared_ptr.hpp> 
#include <boost/bind.hpp> 
#include <list> 
#include <iostream> 


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

    class ClientConnection 
    { 
    public: 
    ClientConnection(io_service & io_s) 
     : m_socket(io_s) {} 
    tcp::socket & socket() { return m_socket; } 
    private: 
    tcp::socket m_socket; 
    }; 

    typedef boost::shared_ptr<ClientConnection> client_connection_ptr; 

    class ClientConnectionAcceptor 
    { 
    public: 
    ClientConnectionAcceptor(unsigned short port) 
     : m_io_service(), 
     m_port(port), 
     m_endpoint(tcp::v4(), m_port), 
     m_acceptor(m_io_service, m_endpoint) 
    { 
     std::cout << "acceptor is open : " << m_acceptor.is_open() << std::endl; 
     client_connection_ptr ccp(new ClientConnection(m_io_service)); 

     m_acceptor.async_accept( 
     ccp->socket(), 
     boost::bind(&ClientConnectionAcceptor::handle_accept,this, 
     ccp, placeholders::error)); 
    } 

    void handle_accept(client_connection_ptr ccp, const boost::system::error_code & error) 
    { 
     std::cout << "in handle_accept" << std::endl; 
     if(!error) 
     { 
     // m_rpc_oracle.AddNewClient(ccp); 
     client_connection_ptr new_ccp(new ClientConnection(m_io_service)); 
     m_acceptor.async_accept( 
      new_ccp->socket(), 
      boost::bind(&ClientConnectionAcceptor::handle_accept,this, 
      ccp, placeholders::error)); 

     } 
    } 

    io_service & io_service() { return m_io_service; } 
    private: 
    boost::asio::io_service m_io_service; 
    tcp::endpoint m_endpoint; 
    tcp::acceptor m_acceptor; 
    unsigned short m_port; 
    }; 


int main() 
{ 
    ClientConnectionAcceptor acceptor(5000); 
    acceptor.io_service().run(); 
}  

回答

2

我发现我能得到这个在我的Windows机器上工作,如果我改变了endpointacceptor到共享指针,而是通过将其作为构造函数的参数创建它们的,我专门创建内部的共享指针构造函数。我不完全确定这是为什么起作用。我唯一的猜测是,可能没有保证构造函数参数是按照它们出现的顺序传递或创建的,因此您可能会尝试创建acceptor,并且endpoint尚未正确初始化?这真是我唯一的猜测。让我知道这是否适合你。我可以通过端口5000上的localhost成功连接。

没有这些更改,我试图通过localhost连接的客户端告诉我连接被主动拒绝。然而,这种安排是成功的,并且似乎偏离了原始代码尽可能少的地步。希望能帮助到你。

#include <boost/asio.hpp> 
#include <boost/shared_ptr.hpp> 
#include <boost/bind.hpp> 
#include <list> 
#include <iostream> 

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

class ClientConnection 
{ 
public: 
    ClientConnection(io_service & io_s) 
    : m_socket(io_s) {} 
    tcp::socket & socket() { return m_socket; } 
private: 
    tcp::socket m_socket; 
}; 

typedef boost::shared_ptr<ClientConnection> client_connection_ptr; 

class ClientConnectionAcceptor 
{ 
public: 
    ClientConnectionAcceptor(unsigned short port) 
    : m_io_service(), 
    m_port(port) 
    { 
    // now initializing endpoint and acceptor as shared pointers inside the constructor 
    m_endpoint = boost::shared_ptr<tcp::endpoint>(new tcp::endpoint(tcp::v4(), m_port)); 
    m_acceptor = boost::shared_ptr<tcp::acceptor>(new tcp::acceptor(m_io_service, *m_endpoint)); 

    std::cout << "acceptor is open : " << m_acceptor->is_open() << std::endl; 
    client_connection_ptr ccp(new ClientConnection(m_io_service)); 

    m_acceptor->async_accept( 
     ccp->socket(), 
     boost::bind(&ClientConnectionAcceptor::handle_accept,this, 
     ccp, placeholders::error)); 
    } 

    void handle_accept(client_connection_ptr ccp, const boost::system::error_code & error) 
    { 
    std::cout << "in handle_accept" << std::endl; 
    if(!error) 
    { 
     // m_rpc_oracle.AddNewClient(ccp); 
     client_connection_ptr new_ccp(new ClientConnection(m_io_service)); 
     m_acceptor->async_accept( 
     new_ccp->socket(), 
     boost::bind(&ClientConnectionAcceptor::handle_accept,this, 
     ccp, placeholders::error)); 

    } 
    } 

    io_service & io_service() { return m_io_service; } 
private: 
    boost::asio::io_service m_io_service; 
    boost::shared_ptr<tcp::endpoint> m_endpoint; 
    boost::shared_ptr<tcp::acceptor> m_acceptor; 
    unsigned short m_port; 
}; 


int main() 
{ 
    ClientConnectionAcceptor acceptor(5000); 
    acceptor.io_service().run(); 
}  

编辑

经过一番深入调查,发现这个问题实际上涉及到了ClientConnectionAcceptor类的初始化列表。在班级定义中,成员m_portm_endpointm_acceptor之后被宣布为。其结果是,即使初始化列表中出现设置的端口号endpointacceptor之前创建的,其实,端口值无效或直到endpointacceptor已创建初始化。将类定义更改为在endpointacceptor之前声明成员m_port可以解决问题。

+0

哇,那确实解决了问题,谢谢。它可能与初始化列表中的初始化顺序有关。我认为这是自上而下的。 –

+0

http://stackoverflow.com/questions/4037219/order-of-execution-in-constructor-initialization-list。用户“in silico”的回应,我的假设,那个初始化列表顺序决定了评估顺序。但是这是决定订单的声明顺序。我仍然必须尝试一下。 –

+0

那么那么回答你的问题,还是有其他的东西? – aardvarkk

1

我编译代码

async_accept.cc:56: error: declaration of ‘boost::asio::io_service& ClientConnectionAcceptor::io_service()’ 
/opt/local/include/boost/asio/io_service.hpp:186: error: changes meaning of ‘io_service’ from ‘class boost::asio::io_service’ 

改变

io_service & io_service() { return m_io_service; } 

io_service & get_io_service() { return m_io_service; } 

似乎解决编译失败得到了一个错误。运行生成的二进制文件为我提供了一个在netstat -l -t中的侦听套接字。