我几天前发了一个问题,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 回答
关闭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
,但使用服务器的接受器仍然是个好主意 .最后,我解决了这个问题,因为我在lauching服务器之前添加了这个命令
感谢大家 .