2011-07-12 40 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中的偵聽套接字。