我无法让这个例子有效 http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/tutorial/tutdaytime3/src.html
我已将端口13更改为1163,因此我无需成为root用户即可开始收听。
我在单独的帖子中运行io_service
。
int main()
{
try
{
boost::asio::io_service io_service;
tcp_server server(io_service);
boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
t.detach();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
string wait;
cin >> wait;
return 0;
}
使用http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/tutorial/tutdaytime1/src.html客户端测试上述服务器时,会显示connection refused
。
netstat --listen
未在1163上显示任何开放端口
我无法弄清楚如何使用boost::asio::async_result<typename Handler>
我对Handler
感到困惑。
工作修改
int main()
{
try
{
boost::asio::io_service io_service;
tcp_server server(io_service);
boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
t.detach();
string wait;
cin >> wait;
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
如果wait
位于try
块内,则代码正常工作!
答案 0 :(得分:2)
如果asio无法侦听端口,则acceptor
的创建或绑定将失败。在您的情况下,您正在使用acceptor_(io_service, tcp::endpoint(tcp::v4(), 13))
创建接受器,这是一个重载:http://www.boost.org/doc/libs/1_62_0/doc/html/boost_asio/reference/basic_socket_acceptor/basic_socket_acceptor/overload3.html
这将直接尝试绑定套接字并在失败时抛出异常。替代方案(在本页底部描述)是创建没有指定端点的套接字,并在其上调用open
和bind
,其中bind
将失败并显示错误(例如,如果套接字已被使用)。在任何情况下,您都不需要等待accept/async_accept
看到错误。
我猜您的问题出在客户端程序中,它仍尝试连接到端口13.您是否已将其更改为使用端口1163?在示例代码中,端口不是直接写入的,但在此处使用了一个众所周知的服务名称:tcp::resolver::query query(argv[1], "daytime");
。 “daytime”引用将告诉解析器使用端口13。
更新:现在,我看到了线程的实际代码,这是一个完全不同的错误:
如果wait
不在try块中,则asio io_service
和tcp_server
几乎立即超出范围,这意味着它们的析构函数被调用。这将停止所有通信。更糟糕的是,分离的线程现在可以在一些悬空指针上运行。作为一般规则,asio对象(io_service eventloop,套接字等)应该都存在于使用它们的线程中。 io_service
的生命周期应该与线程的生命周期相关或更短。套接字的生命周期应该比运行它们的eventloop(io_service
)的生命周期短。使用shared_ptr
或者在设计中加入大量的想法可能是其他使用场景,但这不是我推荐的。