簡體   English   中英

Boost ASIO 異步接受器未打開偵聽端口

[英]Boost ASIO async acceptor not opening a listening port

操作系統:linux 64 位 ARCH。

提升:1.46.1

編譯器:clang++ / GCC。

我有一個代碼片段,它連接了 tcp 接受器,該接受器以 boost::asio 示例( 聊天服務器)為模型。 但是,當我運行該片段時,沒有監聽 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();
}    

我發現如果我將endpointacceptor更改為共享指針,而不是通過在構造函數中將它們作為 arguments 傳遞來創建它們,我可以在我的 Windows 機器上使用它,而是在構造函數中專門創建了共享指針。 我不確定為什么會這樣。 我唯一的猜測是,也許不能保證構造函數 arguments 是按照它們出現的順序傳遞或創建的,因此您可能會嘗試使用尚未正確初始化的endpoint創建acceptor 這真的是我唯一的猜測。 讓我知道這是否適合您。 我可以通過端口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 class 的初始化列表有關。 在 class 定義中,成員m_portm_endpointm_acceptor之后聲明。 結果,即使初始化列表似乎在endpointacceptor創建之前設置了端口號,實際上,端口值直到endpointacceptor已經創建之后才有效或初始化。 更改 class 定義以在endpointacceptor修復問題之前聲明成員m_port

編譯您的代碼時出現錯誤

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中為我顯示一個監聽套接字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM