如何启动一个“事件”时,我的boost :: ASIO TCP服务器刚开始运行(AKA io_ser

2019-08-19 17:24发布

基于一个升压:: ASIO客户端/服务器的关系,我必须从服务器程序启动客户端程序,只有当服务器线程处于“ 等待连接 ”状态。

我的问题是如何使该国的知识呢?

作为样品使用ASIO示例/串行化 链路 ,并更换与该代码server.cpp的主要功能:

#include <conio.h>
#include <concrt.h> // wait function
#include <future>
#include <thread>

void server_thread( std::promise<bool>& run )
{ 
    boost::asio::io_service io_service;
    s11n_example::server server(io_service, 123);
    // too early to run.set_value( true );
    io_service.run();
    // too late to run.set_value( true );
}

int main(int argc, char* argv[])
{
    std::promise<bool> run;
    std::thread thrd( server_thread, boost::ref( run ) );
    thrd.detach(); 

    bool launched = run.get_future().get();
    // server is waiting for connection
    // launch the client
    if( launched )
    {
        int rc = system( "start client.exe localhost 123" );
        if( rc )
            std::cerr << "system failed returning " << rc << std::endl ;
    }
    else
        std::cerr << "server_thread failure" << std::endl ;

    std::cout << "hit a key to exit"  ;
    while( !_kbhit() )
        Concurrency::wait( 100 );

    return 0;
}

谢谢,

Answer 1:

总之, s11n_example::server是在构造函数调用完成后传入的连接将立即排队的状态。


它可能会更容易通过定义状态和操作之间的区别,了解这一点。 一国判定哪些操作系统可以与物体做; 一个应用程序启动执行行动,并可能取决于状态的操作。 例如,当处于打开状态的插座,所述OS将排队的数据; 读取操作检索排队的数据。 这同样适用于该受体。 当受体处于状态时,OS将排队的连接; 接收操作将完成连接,从队列中删除。

一个acceptor[状态]转换()如下:

     .----> [closed] ------.     [closed]:    socket not open
     |                     |     [opened]:    socket open but not listening for
     |                     V                  connections
  close() <------.      open()   [listening]: incoming connections will be
     ^           |         |                  queued until accepted(), causing
     |           |         V                  the connection to be established
[listening]      '---- [opened]
     ^                     |
     |                     |
     '------ listen() <----'

各种重载构造将导致acceptor开始其在闭合,打开或监听状态的寿命。 在的情况下s11n_example::server ,受体构建与端点,所以这种过载会导致受体处于监听状态的工后之中。 它是做等价的:

using boost::asio::ip::tcp;
tcp::endpoint endpoint_(tcp::v4(), 123);
tcp::acceptor acceptor_(io_service); // closed state
acceptor.open(endpoint_.protocol()); // opened state
acceptor.bind(endpoint);
acceptor.listen();                   // listening state

因此,许可后设置server被构造之前和io_service.run()

void server_thread(std::promise<bool>& run)
{ 
    boost::asio::io_service io_service;
    s11n_example::server server(io_service, 123);
    // The server's acceptor is in a listening state, so connection attempts
    // will be queued even without the io_service event loop running.  The
    // server also has an outstanding asynchronous accept operation.
    run.set_value(true);
    // Run the service, this will start an asynchronous loop that accepts 
    // connections.
    io_service.run();
}

一个微妙需要注意的是Boost.Asio的的受体不提供:

  • 用于接受连接基于反应器操作。 因此,无法检测当连接准备好接受(即,连接被排队并等待被接受)。
  • 检测的更高级别的方式,如果该acceptor处于监听状态。 然而,这可以通过查询受体的完成native_handle 。 例如,使用getsockopt()得到的值SOL_SOCKET/SO_ACCEPTCONN


文章来源: How to launch an “event” when my Boost::asio tcp server just start running ( AKA io_service.run() )?