写入套接字后管道破裂 [英] Broken pipe after writing to socket

查看:110
本文介绍了写入套接字后管道破裂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在网络库中,如果我手动 run() restart() io_context ,我可以对网络进行异步写入.

In my network library I can do asynchronous writes to the network if I run() and restart() the io_context manually.

我现在正在尝试通过添加线程池来扩展规模:

I'm now trying to make things scale by adding a thread pool:

.hpp

struct pool : public std::enable_shared_from_this<pool> {
  pool(const pool &) = delete;
  auto operator=(const pool &) -> pool & = delete;
  explicit pool(pool_parameters config, db_parameters params) noexcept;

  asio::io_context m_io_context;

  asio::thread_pool m_workers;

  asio::executor_work_guard<asio::io_context::executor_type> m_work_guard;

  /// \brief Container to hold connections.
  std::vector<std::unique_ptr<dbc::connection>> m_connections;
};

.cpp

pool::pool(pool_parameters config, db_parameters params) noexcept
    : m_config{std::move(config)},
      m_params{std::move(params)},
      m_work_guard{asio::make_work_guard(m_io_context)},
      m_workers{m_config.thread_pool_size} {
  m_connections.reserve(m_config.connection_pool_size);
  asio::post(m_workers, [&]() { m_io_context.run(); });
}

管理连接的人:

.hpp

struct abstract_connection : connection {
  explicit abstract_connection(const std::shared_ptr<pool> &pool) noexcept;

  ~abstract_connection() override;
      packet m_buffer;

      asio::local::stream_protocol::endpoint m_endpoint;

      asio::generic::stream_protocol::socket m_socket;

      asio::io_context::strand m_strand;
    };

.cpp

abstract_connection::abstract_connection(const std::shared_ptr<pool> &pool) noexcept
        : m_params{pool->m_params},
          m_config{pool->m_config},
          m_endpoint{pool->m_config.socket},
          m_socket{pool->m_io_context},
          m_strand{pool->m_io_context} {
      m_socket.connect(m_endpoint);
      m_socket.non_blocking(true);
    }

abstract_connection::~abstract_connection() {
      std::error_code ec;
      m_socket.shutdown(asio::generic::stream_protocol::socket::shutdown_both, ec);
      m_socket.close();
    }

现在到了令人困惑的公园.在具体连接对象的ctor上,我需要进行一次握手,并在同一类的析构函数上进行一次握手.不会发生这种情况是因为套接字对象的行为似乎很奇怪:

Now comes the confusing park. On the ctor of a concrete connection object I need to do a handshake, along with a handshake on the destructor of the same class. Which does not happen because the socket object seems to be behaving in odd ways:

如果我异步发送数据,则没有任何内容写入套接字,有时会出现管道破裂错误:

If I send data asyncrhonously, nothing gets written to the socket and sometimes I get a broken pipe error:

asio::dispatch(m_strand, [&]() {
          m_buffer = write::startup(m_params);
          asio::async_write(m_socket, asio::buffer(m_buffer), [](std::error_code ec, std::size_t len) {});
        });

如果我执行同步写入,则在从套接字读取之前会遇到管道破裂的错误:

If I do a synchronous write I get a broken pipe error before I can read from the socket:

std::error_code ec;
        auto startup = write::startup(m_params);
        asio::write(m_socket, asio::buffer(startup), ec);
        if (set_error(ec)) {
          std::cerr << " XXX " << ec.message() << std::endl;
          return;
        }

        m_buffer.reserve(327);
        asio::read(m_socket, asio::buffer(m_buffer), ec);
        std::cerr << ec.message() << std::endl;
        std::cerr << m_buffer.size() << std::endl;

连接是通过unix套接字完成的,并且我在两者之间都装有socat,因此我可以看到数据来来去去,以及断开的管道消息.尝试使用第三方工具连接到遥控器的方法可行,所有相关数据都出现在socat中,因此我认为问题出在我的代码中.

The connection is being done over a unix socket and I have socat sitting between both, so I can see data coming and going, along with the broken pipe messages. Trying to connect to the remote using a third party tool works, with all relevant data appearing in socat, so I believe the problem is in my code.

如何调试套接字发生的事情?

How can I debug what is going on with the socket?

推荐答案

我通过制作套接字阻塞( non_blocking(false))解决了这个问题,没有Superlokkus的回答我就不会想到

I solved the problem by making the socket blocking (non_blocking(false)) which I would not have thought of without Superlokkus' answer.

这篇关于写入套接字后管道破裂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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