ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – 当我的Boost :: asio tcp服务器刚开始运行时如何启动“事件”(AKA io_service.run())?

2019-09-29 10:12:12  阅读:232  来源: 互联网

标签:c c11 boost boost-asio


基于boost :: asio客户端/服务器关系,我必须仅在服务器线程处于“等待连接”状态时才从服务器程序启动客户端程序.

我的问题是如何掌握该国的知识?

作为样本使用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处于一种状态,在构造函数调用完成后,传入连接将立即排队.

通过定义状态和操作之间的区别可能更容易理解这一点.状态确定操作系统可以对对象执行的操作;应用程序启动执行操作的操作,并且可能依赖于状态.例如,当套接字处于打开状态时,OS将排队数据;读操作检索排队的数据.这同样适用于受体.当接受器处于侦听状态时,操作系统将排队连接;接受操作将完成连接,将其从队列中删除.

接受者的[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() <----'

各种重载的构造函数将导致接受器在闭合,打开或侦听状态下开始其生命周期.在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

因此,可以在构造服务器之后和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的接受者不提供:

>用于接受连接的基于反应器的操作.因此,不可能检测何时准备接受连接(即,连接排队并等待被接受).
>检测接受器是否处于侦听状态的更高级别方法.然而,这可以通过查询接受器的native_handle来完成.例如,使用getsockopt()来获得SOL_SOCKET / SO_ACCEPTCONN的值.

标签:c,c11,boost,boost-asio
来源: https://codeday.me/bug/20190929/1830968.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有