Boost ASIO 异步接受器未打开侦听端口
操作系统:Linux 64 位 ARCH。
升压:1.46.1
编译器:clang++ / GCC。
我有一个代码片段,其中包含以 boost::asio 示例为模型的 tcp 接受器的线路(聊天服务器)。但是,当我运行该片段时,在 netstat waiting(linux) 中没有显示正在监听的 TCP 套接字。但是,聊天服务器示例在编译后确实会显示出来。有人可以指出我做错了什么吗?
#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();
}
OS : linux 64 bit ARCH.
BOOST : 1.46.1
COMPILER : clang++ / GCC.
I have a code fragment that has the wire up of a tcp acceptor modelled on a boost::asio example (Chat Server). However, when I run the fragment, No listening TCP socket shows up in a netstat listening(linux) . However, the chat server example, when compiled, does show up. Could someone please point out what I am doing wrong ?
#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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我发现如果我将端点和接受器更改为共享指针,而不是通过将它们作为参数传递来创建它们,我可以让它在我的 Windows 计算机上工作。构造函数,我专门在构造函数内创建了共享指针。我不太确定为什么会这样。我唯一的猜测是,也许无法保证构造函数参数按照它们出现的顺序传递或创建,因此您可以尝试使用
端点
创建接受器
那还没有正确初始化吗?这确实是我唯一的猜测。让我知道这是否适合您。我可以通过端口5000
上的localhost
成功连接。如果没有这些更改,我尝试通过 localhost 连接的客户端告诉我连接被主动拒绝。然而,这种安排是成功的,并且似乎与原始代码的偏差尽可能小。希望有帮助。
编辑
经过进一步调查,发现问题实际上与
ClientConnectionAcceptor
类的初始化列表有关。在类定义中,成员m_port
是在m_endpoint
和m_acceptor
之后声明的。因此,尽管初始化列表似乎在创建端点
和接受器
之前设置了端口号,但事实上,端口号在创建端点
和接受器
之后之前,该值无效或初始化。更改类定义以在endpoint
和acceptor
之前声明成员m_port
可以解决此问题。I found that I could get this to work on my Windows machine if I changed the
endpoint
andacceptor
to shared pointers, and instead of creating them by passing them as arguments in the constructor, I specifically created the shared pointers inside the constructor. I'm not exactly sure why this works. My only guess is that perhaps there are no guarantees that the constructor arguments are passed or created in the order they appear, and thus you may try to create theacceptor
with anendpoint
that isn't correctly initialized yet? That's really my only guess. Let me know if this works for you. I could successfully connect vialocalhost
on port5000
.Without these changes, the client that I tried to connect with via
localhost
told me the connection was actively refused. This arrangement was successful, however, and seems to deviate as little as possible from your original code. Hope it helps.EDIT
After some further investigation, it was discovered that the problem was actually related to the initializer list for the
ClientConnectionAcceptor
class. In the class definition, the memberm_port
was declared afterm_endpoint
andm_acceptor
. As a result, even though the initializer list appeared to set up the port number before theendpoint
andacceptor
were created, in fact, the port value was not valid or initialized until after theendpoint
andacceptor
were already created. Changing the class definition to have the memberm_port
declared beforeendpoint
andacceptor
fixes the problem.编译代码时出现错误,
更改
为
似乎可以解决编译器故障。运行生成的二进制文件会在
netstat -l -t
中显示一个监听套接字。I got an error when compiling your code
changing
to
seems to resolve the compiler failure. Running the resulting binary shows a listen socket in
netstat -l -t
for me.