Boost ASIO异步接收器不打开侦听端口
Boost ASIO async acceptor not opening a listening port
操作系统:linux 64位ARCH.
BOOST: 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();
}
我发现如果我将endpoint
和acceptor
更改为共享指针,我可以在我的Windows机器上工作,而不是通过将它们作为参数传递给构造函数来创建它们,我专门在构造函数中创建共享指针。我不太确定为什么会这样。我唯一的猜测是,也许没有保证构造函数参数是按照它们出现的顺序传递或创建的,因此您可以尝试使用尚未正确初始化的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
类的初始化列表有关。在类定义中,成员m_port
在 m_endpoint
和m_acceptor
之后声明为。因此,尽管初始化列表在 endpoint
和acceptor
创建之前设置了端口号,但实际上,直到之后的已经创建了endpoint
和acceptor
,端口值才有效或初始化。修改类定义,使成员m_port
在endpoint
和acceptor
之前声明,可以解决这个问题。
在编译代码时出现错误
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
中的侦听套接字。
- 提升::Asio 异步聊天客户端停止与服务器通信
- 某些 boost::asio 异步函数是否将处理程序连接到操作,以便处理程序被触发一次?
- 提升 ASIO:异步写入,同步
- Boost.Asio 异步服务器.限制为一个连接
- 运行 boost::asio 异步服务器以及命令循环
- Boost ASIO-异步堆栈 民意调查
- boost::bind with member functions(作为boost::asio异步写入处理程序)
- Boost ASIO:异步数据读数
- UDP Boost ASIO 异步客户端挂起
- 关于boost.asio异步睡眠
- Boost Asio异步:服务器已向客户端发送消息
- 使用带有boost::asio异步操作的自定义streambuf
- C++ ASIO:异步套接字和线程
- 在 boost asio 异步服务器中执行计算 taks
- 如何阻止 boost::asio 异步读取混淆
- 接受Boost ASIO异步处理程序
- 我可以在 boost::asio 异步模式下创建和接受套接字时使用 boost::shared_ptr 吗?
- 如何安全地取消提升 ASIO 异步接受操作
- 使用boost::asio异步发送自动变量.这可能吗?
- 如何调用boost::asio异步函数