简体   繁体   English

Boost.Asio异步服务器。 仅限一个连接

[英]Boost.Asio asynchronous server. Limit to one connection

I'm fairly new to Boost.Asio and I want to develop an asynchronous server that limits the number of active connections to one. 我是Boost.Asio的新手,我想开发一个异步服务器,将活动连接数限制为一个。 In other words, when a connection is established, additional connections will be denied. 换句话说,建立连接后,其他连接将被拒绝。 Once that connection is closed, another one can take its spot. 一旦该连接关闭,另一个就可以使用它。

It's not immediately clear how to accomplish this and still be able to re-connect if the connection gets closed. 目前尚不清楚如何完成此操作,如果连接关闭,仍然能够重新连接。

Could someone provide a simple example of how to do this? 有人可以提供一个简单的示例来说明如何执行此操作吗?

EDIT: How would you take the Boost.Asio Asynchronous Server example code and edit it to limit the number of connections? 编辑:您将如何使用Boost.Asio异步服务器示例代码并对其进行编辑以限制连接数?

Just don't accept the new connection until the previous is done. 只是在完成以前的连接后才接受新的连接。

Simplest possible program I can come up with: 我可以想出的最简单的程序:

#define BOOST_ASIO_HAS_CHRONO 1
#include <boost/asio.hpp>
#include <iostream>
#include <chrono>

namespace ba = boost::asio;
using ba::ip::tcp;
using boost::system::error_code;

class Server {
    ba::io_service _svc;
    tcp::acceptor _acc{_svc};
    tcp::socket _conn{_svc};

    ba::streambuf _request, _response;

  public:
    void start(unsigned short port, std::chrono::high_resolution_clock::duration time) {
        _acc.open(tcp::v4());
        _acc.bind({{}, port});
        _acc.listen(5);

        do_accept();

        _svc.run_for(time);
    }

  private:
    void do_accept() {
        if (_conn.is_open())
            _conn.close();

        _acc.async_accept(_conn, [=](error_code ec) { handle_accept(ec); });
    }

    void handle_accept(error_code ec) {
        if (!ec) std::cout << "Accepted: " << _conn.remote_endpoint() << ", " << ec << " (" << ec.message() << ")\n";
        else     std::cout << "Accepted, " << ec << " (" << ec.message() << ")\n";

        ba::async_read_until(_conn, _request, "\r\n", [=](error_code ec, size_t xfr) { handle_read(ec, xfr); });
    }

    void handle_read(error_code ec, size_t transferred) {
        std::cout << "Read request: " << transferred << " bytes, " << ec << " (" << ec.message() << ")\n";

        std::vector<char> v(std::istreambuf_iterator<char>(&_request), {});
        std::reverse_copy(begin(v), end(v), std::ostreambuf_iterator<char>(&_response));

        ba::async_write(_conn, _response, [=](error_code ec, size_t xfr) { handle_write(ec, xfr); });
    }

    void handle_write(error_code ec, size_t transferred) {
        std::cout << "Written request: " << transferred << " bytes, " << ec << " (" << ec.message() << ")\n";

        do_accept(); // ONLY HERE initiate new accept. Could be back-log pending
    }
};

using namespace std::chrono_literals;
int main() {
    Server s;

    s.start(6767, 3s); // For demo, run 3 seconds
}

Prints 版画

./sotest & sleep .5; for w in Hello Bye; do echo -ne "$w world\!\\r\\n" | netcat localhost 6767; done
Accepted: 127.0.0.1:43764, system:0 (Success)
Read request: 15 bytes, system:0 (Success)

!\dlrow olleHWritten request: 15 bytes, system:0 (Success)
Accepted: 127.0.0.1:43766, system:0 (Success)
Read request: 13 bytes, system:0 (Success)

!\dlrow eyBWritten request: 13 bytes, system:0 (Success)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM