gpt4 book ai didi

c++ - 如何在我的 Boost::asio tcp 服务器刚开始运行时启动 "event"(AKA io_service.run())?

转载 作者:行者123 更新时间:2023-11-30 01:59:48 26 4
gpt4 key购买 nike

基于 boost::asio 客户端/服务器关系,只有当服务器线程处于“等待连接”状态时,我才必须从服务器程序启动客户端程序。< br/>
我的问题是如何了解该状态?

作为示例使用 asio example/serialization link , 并将 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;
}

谢谢,

最佳答案

简而言之,s11n_example::server 处于构造函数调用完成后传入连接将立即排队的状态。


定义状态和操作之间的区别可能更容易理解这一点。状态决定了操作系统可以对对象做什么;应用程序启动执行操作的操作,并且可能取决于状态。例如,当套接字处于打开 状态时,操作系统会将数据排队; read 操作检索排队的数据。这同样适用于受体。当接受器处于监听状态时,操作系统将对连接进行排队; accept 操作将完成连接,将其从队列中移除。

一个acceptor[states]transitions()如下:

     .----> [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的情况下,接受器是用端点构造的,所以 this过载将导致接受器在构建后处于监听状态。这相当于做:

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()之前设置promise:

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 的接受器不提供:

  • 接受连接的基于 Reactor 的操作。因此,无法检测连接何时准备好被接受(即连接已排队等待被接受)。
  • 检测 acceptor 是否处于监听状态的更高级别的方法。然而,这可以通过查询接受者的 native_handle 来完成。 .例如,使用 getsockopt()获取 SOL_SOCKET/SO_ACCEPTCONN 的值。

关于c++ - 如何在我的 Boost::asio tcp 服务器刚开始运行时启动 "event"(AKA io_service.run())?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15829165/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com