c++ - Boost.Asio 异步服务器。限制为一个连接

标签 c++ asynchronous boost boost-asio

我是 Boost.Asio 的新手,我想开发一个将事件连接数限制为一个的异步服务器。换句话说,当建立连接时,将拒绝其他连接。一旦该连接关闭,另一个连接就可以取代它。

目前还不清楚如何实现这一点,并且在连接关闭时仍然能够重新连接。

有人可以提供一个简单的例子来说明如何做到这一点吗?

编辑:您将如何使用 Boost.Asio 异步服务器 example code并对其进行编辑以限制连接数?

最佳答案

在上一个连接完成之前不要接受新连接。

我能想到的最简单的程序:

#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
}

打印

./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)

关于c++ - Boost.Asio 异步服务器。限制为一个连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48431848/

相关文章:

c++ - 句子转换器在换行时不起作用

c++ - 如何在不阻塞或轮询的情况下从子进程的 STDOUT 接收输出

c++ - I/O 完成端口的异步操作返回 0 字节传输

c++ - boost fusion 和运行时收集增长

c++ - 再次出现错误 C2248

c++ - jObjectArray 尚未声明

c++ - 给优化器更大的 "License"

c - 如何在异步模式下使用SIGALRM和SIGPOLL?

javascript - jQuery ajax 异步 'true' 让我的网络应用程序卡住,直到数据返回

c++ - 我如何判断 boost::thread 是否已完成执行?