c++ - How to launch an "event" when my Boost::asio tcp server just start running ( AKA io_service.run() )? -
based on boost::asio client/server relationship, have launch client program server program when server thread in "waiting connected" state.
question how have knowledge of state ?
as sample use asio example/serialization link, , replace main function of server.cpp code:
#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); // run.set_value( true ); io_service.run(); // late 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 waiting connection // launch 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 key exit" ; while( !_kbhit() ) concurrency::wait( 100 ); return 0; }
thanks,
in short, s11n_example::server
in state incoming connections queued after constructor call has completed.
it may easier understand defining distinction between state , operations. state determines os can object; application initiates operations perform actions , may depend on state. example, when socket in open state, os queue data; read operation retrieves queued data. same applies acceptors. when acceptor in listen state, os queue connections; accept operation complete connection, removing queue.
an acceptor
's [states] , transitions() follows:
.----> [closed] ------. [closed]: socket not open | | [opened]: socket open not listening | v connections close() <------. open() [listening]: incoming connections ^ | | queued until accepted(), causing | | v connection established [listening] '---- [opened] ^ | | | '------ listen() <----'
the various overloaded constructors result in acceptor
starting lifetime in closed, opened, or listening state. in case of s11n_example::server
, acceptor constructed endpoint, this overload result in acceptor being in listening state post-construction. equivalent of doing:
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
therefore, promise can set after server
constructed , before io_service.run()
:
void server_thread(std::promise<bool>& run) { boost::asio::io_service io_service; s11n_example::server server(io_service, 123); // server's acceptor in listening state, connection attempts // queued without io_service event loop running. // server has outstanding asynchronous accept operation. run.set_value(true); // run service, start asynchronous loop accepts // connections. io_service.run(); }
one subtlety note boost.asio's acceptors not provide:
- reactor based operations accepting connections. thus, not possible detect when connection ready accepted (i.e. connection queued , waiting accepted).
- an higher-level way detect if
acceptor
in listening state. nevertheless, may accomplished querying acceptor'snative_handle
. example, usinggetsockopt()
value ofsol_socket/so_acceptconn
.
Comments
Post a Comment