首页 文章

为什么在boost asio应用程序中导致很多CLOSE_WAIT?

提问于
浏览
3

我几天前发了一个问题,why my app based on boost::asio didn't accept new connection我觉得它已经解决了 .

但它不是,今天我有时可以重现错误 . 停止/启动连接到我的TCP服务器的2000客户端应用程序后 . 在某些情况下,许多连接显示为CLOSE_WAIT .

我使用下面的代码手动关闭连接:

void CloseSocket() {
    try {
      socket.shutdown(tcp::socket::shutdown_both);
      socket.close();
      BOOST_LOG_TRIVIAL(warning) << "close the connection";
    } catch (std::exception& e) {
      BOOST_LOG_TRIVIAL(warning) << "thread id: " << this_thread::get_id() << " " << e.what();
    }
  }

还要设置要重用的地址

acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));

有些人说不建议手动关闭套接字,让asio为你做 . 但有些人说你应该在关闭套接字之前调用shutdown . 我使用后一种方式,但问题仍然存在 .

2 回答

  • 3

    关闭TCP连接时:

    • 发起方进入主动关闭 . 这会将启动器的连接置于 TIME_WAIT 状态,从而防止地址被重用,以防止延迟数据包作为新连接的一部分被接收 . 即使连接处于 TIME_WAIT 状态,socket_base::reuse_address选项也允许重用地址 . 这通常用于允许服务器重新启动并立即开始侦听同一端口 .

    • 接收方进入被动关闭 . 接收器的连接将保持在 CLOSE_WAIT 状态,直到套接字关闭 . 当套接字关闭时,它允许释放地址并由内核重用 .

    正如Igor R.简明扼要地建议的那样,可以通过验证所有路径允许套接字关闭来解决问题 . 基于your other question,给定 ClientType 聚合套接字, ClientType 实例由 shared_ptr 管理, ClientType 实例可能永远不会被删除,因为套接字在销毁期间将关闭 .

    此外,虽然 socket_base::reuse_address 不会影响 CLOSE_WAIT ,但使用服务器的接受器仍然是个好主意 .

  • 0

    最后,我解决了这个问题,因为我在lauching服务器之前添加了这个命令

    ulimit -n 10240

    感谢大家 .

相关问题