如何确定 boost async_accept 是否正在侦听端口

how to determine whether boost async_accept is listening on a port or not

我无法让这个例子工作 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;
}

如果 waittry 块内,代码有效!

如果 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

这将直接尝试绑定套接字,如果失败则抛出异常。另一种方法(在本页底部进行了描述)是创建没有指定端点的套接字并在其上调用 openbind,其中 bind 将失败并出现错误 (例如,如果套接字已在使用中)。在任何情况下,您都不需要等待 accept/async_accept 才能看到错误。

我猜你的问题出在客户端程序上,它仍然尝试连接到端口 13。你是否将其更改为使用端口 1163?在示例代码中并没有直接写端口,而是在这里使用了一个well-known服务名:tcp::resolver::query query(argv[1], "daytime");。 "daytime" 引用将告诉解析器使用端口 13。

更新: 现在我看到了线程的实际代码,这是一个完全不同的错误:

如果 wait 不在 try 块内,asio io_servicetcp_server 将几乎立即超出范围,这意味着调用它们的析构函数。这将停止所有通信。更糟糕的是,分离的线程现在对一些悬空指针进行操作。作为一般规则,asio 对象(io_service 事件循环、套接字等)都应该存在于使用它们的线程中。 io_service 的生命周期应该与线程的生命周期相关或更短。套接字的生命周期应短于运行它们的事件循环 (io_service) 的生命周期。其他使用场景可能通过使用 shared_ptr's 或在设计中投入很多想法来实现,但这不是我推荐的。