提高ASIO TCP异步服务器不是异步? [英] Boost asio TCP async server not async?

查看:176
本文介绍了提高ASIO TCP异步服务器不是异步?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的<一个提供的code href=\"http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp11/echo/async_tcp_echo_server.cpp\"相对=nofollow>升压例如。

服务器只接受每次1个连接。这意味着,没有新的连接,直到在当前是关闭的。

The server only accepts 1 connection at a time. This means, no new connections until the current one is closed.

如何使上述code,同时承担无限连接?

How to make the above code accept unlimited connections at the same time?

#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class session
  : public std::enable_shared_from_this<session>
{
public:
  session(tcp::socket socket)
    : socket_(std::move(socket))
  {
  }

  void start()
  {
    do_read();
  }

private:
  void do_read()
  {
    auto self(shared_from_this());
    socket_.async_read_some(boost::asio::buffer(data_, max_length),
        [this, self](boost::system::error_code ec, std::size_t length)
        {
          if (!ec)
          {
            boost::this_thread::sleep(boost::posix_time::milliseconds(10000));//sleep some time
            do_write(length);
          }
        });
  }

  void do_write(std::size_t length)
  {
    auto self(shared_from_this());
    boost::asio::async_write(socket_, boost::asio::buffer(data_, length),
        [this, self](boost::system::error_code ec, std::size_t /*length*/)
        {
          if (!ec)
          {
            do_read();
          }
        });
  }

  tcp::socket socket_;
  enum { max_length = 1024 };
  char data_[max_length];
};

class server
{
public:
  server(boost::asio::io_service& io_service, short port)
    : acceptor_(io_service, tcp::endpoint(tcp::v4(), port)),
      socket_(io_service)
  {
    do_accept();
  }

private:
  void do_accept()
  {
    acceptor_.async_accept(socket_,
        [this](boost::system::error_code ec)
        {
          if (!ec)
          {
            std::make_shared<session>(std::move(socket_))->start();
          }

          do_accept();
        });
  }

  tcp::acceptor acceptor_;
  tcp::socket socket_;
};

int main(int argc, char* argv[])
{
  try
  {
    if (argc != 2)
    {
      std::cerr << "Usage: async_tcp_echo_server <port>\n";
      return 1;
    }

    boost::asio::io_service io_service;

    server s(io_service, std::atoi(argv[1]));

    io_service.run();
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}

正如你所见,该程序等待睡眠,它不会抢在此期间的第二个连接。

As you see, the program waits for the sleep and it doesn't grab a second connection in the meantime.

推荐答案

您正在做它运行在供应您io_service对象的唯一线程处理程序中同步等待。这使得短耳等待与调用处理任何新的请求。

You're doing a synchronous wait inside the handler which runs on the only thread that serves your io_service. This makes Asio wait with invoking the handlers for any new requests.


  1. 使用 deadline_time wait_async

void do_read() {
    auto self(shared_from_this());
    socket_.async_read_some(boost::asio::buffer(data_, max_length),
                            [this, self](boost::system::error_code ec, std::size_t length) {
        if (!ec) {
            timer_.expires_from_now(boost::posix_time::seconds(1));
            timer_.async_wait([this, self, length](boost::system::error_code ec) {
                    if (!ec)
                        do_write(length);
                });
        }
    });
}

定时器_ 字段是的boost :: 的ASIO :: deadline_timer 成员会议

Where the timer_ field is a boost::asio::deadline_timer member of session

作为-穷人的解决方案中添加更多的线程(这只是意味着,如果有更多的要求比有线程来处理他们同时到达,它仍然会阻塞,直到第一个线程可用拿起新的请求)

as a poor-man's solution add more threads (this simply means that if more requests arrive at the same time than there are threads to handle them, it will still block until the first thread becomes available to pick up the new request)

boost::thread_group tg;
for (int i=0; i < 10; ++i)
    tg.create_thread([&]{ io_service.run(); });

tg.join_all();


这篇关于提高ASIO TCP异步服务器不是异步?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆