【问题标题】:How to make a multi-client server with synchronous dataread/write functions?如何制作具有同步数据读/写功能的多客户端服务器?
【发布时间】:2019-06-13 17:49:10
【问题描述】:

好的,所以我可能在这里遇到了一个大问题。一直以来,我的代码都基于我可能想要的东西,也就是说,我正在将同步 boost::asio 函数与可以同时拥有多个客户端的服务器一起使用时间。这里是:

void session(tcp::socket socket, std::vector<Player>* pl)
{
debug("New connection! Reading username...\n");

/* ...Username verification code removed... */

debug("Client logged in safely as ");
debug(u->name);
debug("\n");

for (;;)
{
    boost::array<unsigned char, 128> buf;

    size_t len = socket.read_some(boost::asio::buffer(buf), error);

    if (error == boost::asio::error::eof)
    {
        debug("Connection ended.\n");
        break; // Connection closed cleanly by peer.
    }
    else if (error)
        throw boost::system::system_error(error); // Some other error.

    DataHeader ins = static_cast<DataHeader>(buf.data()[0]);

    std::vector<unsigned char> response;

    /* ... Get appropiate response... */

    // send response
    boost::system::error_code ignored_error;
    boost::asio::write(socket, boost::asio::buffer(response), ignored_error);
    //debug("Sent ");
    //debug(response.size());
    //debug("B to client.\n");
}
}

从代码中可以看出,我在非理想场景中使用了read_somewrite 函数。现在,问题是,我如何让这段代码同时用于多个客户端?好吧,我使用了线程:

int main()
{
try
{
    boost::asio::io_context io_context;

    tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 13));

    debug("Ready.\n");
    for (;;)
    {
        std::thread(session, acceptor.accept(), &players).detach(); // Accept incoming clients
    }
}
catch (std::exception& e)
{
    std::cerr << e.what() << std::endl;
}

return 0;
}

现在,直到最近我才开始在一台服务器上同时测试多个客户端,我从未遇到过此设置的问题。这使得服务器崩溃了很多次,直到现在,我还以为问题只是连接问题。但是,现在我开始怀疑,“问题可能出在同步函数上吗?”

到目前为止,我看到的所有多客户端服务器示例都使用异步函数,也许是因为需要它们。所以,我的最后一个问题是,我是否真的需要异步函数?这段代码有什么问题导致它崩溃吗?最后,如果需要异步函数,我该如何实现它们?非常感谢!

【问题讨论】:

  • 无休止的循环吐出分离线程在多个层面上都是错误的......是的,你肯定需要在某个时候切换到异步函数(在你需要处理超过 ~10 个客户端之后同时)。
  • 为什么?线程慢吗?
  • 该循环基本上会不断产生越来越多的线程,直到系统无法分配新线程导致资源耗尽。通过分离线程,您基本上会忘记它们。
  • 哦。好吧,我不只是为了方便而使用线程,我实际上需要跟踪哪个线程属于哪个玩家。这可以在异步函数中实现吗?
  • 根据您希望同时连接的客户端数量,播放器和线程之间的一对一关系也是次优的。人们通常做的是有一个线程池和一个 nthreads : nplayers 关系,其中 nthreads

标签: c++ multithreading networking boost-asio


【解决方案1】:

正如用户 VTT 所指出的,虽然这种方法可能有点作用,但由于资源耗尽,最好切换到异步函数,所以,我将重做整个服务器来实现它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-22
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多