2016-11-24 125 views
1

在我开始之前,我只是想尝试一些东西。我还不知道我是否想做一个大项目。Boost ASIO socket io_service.run blocking

我尝试使用Boost创建TCP套接字服务器,因为它比winsock更容易。至少,所以我想,但它不工作,我想要它。应该发生什么:

  1. 读取配置
  2. 启动TCP套接字服务器
  3. 运行_acceptor.async_accept
  4. 运行io_service.run

现在,我到了一点我的插座服务器的工作原理并接受连接。但是,我无法再进行用户输入,因为io_service.run会阻止我的服务器的其余部分。我一定做错了什么。

tcp_listener.h:

#pragma once 
#include <boost/asio.hpp> 
class tcp_listener 
{ 
public: 
    tcp_listener(boost::asio::io_service& io_service, std::string ip, short port); 
    static void start(tcp_listener* ptr); 
    void start_accepting(); 
private: 
    boost::asio::ip::tcp::acceptor _acceptor; 
    boost::asio::ip::tcp::socket _socket; 
}; 

tcp_listener.cpp:

#include "tcp_listener.h" 
#include "logger.h" 
#include <boost/asio.hpp> 
#include <boost/shared_ptr.hpp> 
#include <boost/bind.hpp> 
#include <boost/thread.hpp> 
#include <memory> 

tcp_listener::tcp_listener(boost::asio::io_service& io_service, std::string ip, short port) 
    : _acceptor(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4::from_string(ip), port)), 
     _socket(io_service) 
{ 
    logger::log_main("Network bound on %s.%d", _acceptor.local_endpoint().address().to_string().data(), _acceptor.local_endpoint().port()); 

    start_accepting(); 

    io_service.run(); 
} 

void tcp_listener::start(tcp_listener* ptr) 
{ 
    ptr->start_accepting(); 
} 

void tcp_listener::start_accepting() 
{ 
    _acceptor.async_accept(_socket, [this](boost::system::error_code ec) 
    { 
     if (!ec) 
     { 
      logger::log_main("New connection %s", _socket.remote_endpoint().address().to_string().data()); 
      //std::make_shared<tcp_client>(std::move(socket_))->start_receiving(); 
     } 
     else 
     { 
      _acceptor.close(); 
     } 

     start_accepting(); 
    }); 
} 

engine.h:

#pragma once 
#include "configuration.h" 
class engine 
{ 
public: 
    static void boot(); 
    static void destroy(); 
    static configuration* get_config(); 
private: 
    static configuration* config; 
}; 

engine.cpp:

#include "engine.h" 
#include "tcp_listener.h" 
#include <boost/thread.hpp> 
#include <boost/bind.hpp> 
configuration* engine::config; 
void engine::boot() 
{ 
    engine::config = new configuration("config.cnf"); 

    boost::asio::io_service io_service; 
    tcp_listener& list = tcp_listener(io_service, engine::config->get_value("network.ip"), atoi(engine::config->get_value("network.port").data())); 
} 

void engine::destroy() 
{ 
    delete engine::config; 
} 

configuration* engine::get_config() 
{ 
    return engine::config; 
} 

Main.cpp的:

#include "engine.h" 
#include <iostream> 

int main() 
{ 
    engine::boot(); 

    for (;;) 
    { 
     std::string input; 
     std::cin >> input; 

     if (input == "exit") 
     { 
      engine::destroy(); 

      break; 
     } 
    } 

    return 0; 
} 

...我已经寻找5个多小时,我试过一百万的东西,没有什么工作。我试图把它放在一个线程中,导致我处于例外状态。或者套接字服务器本身不起作用。

用户输入对重新加载特定的缓存数据或关闭应用程序或类似的东西很有用。

回答

2

这是设计。

只是run服务在一个单独的线程。

std::thread th([&] { io_service.run(); }); // example 

小心共享资源上的线程同步。

io_service是线程安全的(除了特殊操作,如构造,破坏,重置)。因此,如果您必须执行需要同步的任务,那么post()service将是最简单的。

只要你只有1个线程run -ning特定io_service情况下,你不需要额外的同步(所谓逻辑的或隐含的股¹)。

¹Why do I need strand per connection when using boost::asio?

+0

如果我这样做,我会得到一个调试错误。我现在有:'std :: thread th([&] {io_service.run();});'我试着做'th.detach()',但是它给出了错误。没有分离,我也会得到错误。 –

+2

“错误”。真。如果你不确定如何在C++ 11中使用线程,那么'std :: thread'的文档会有所帮助(这就是为什么我有'//例子'注释,你必须完成它) – sehe

+0

yes,调试错误。 –

相关问题