C++ 为什么在boost asio应用程序中导致许多关闭等待?
几天前我发布了一个问题, 我还以为问题解决了 但事实并非如此,今天我有时可以重现错误。停止/启动连接到我的TCP服务器的2000个客户端应用程序后。在某些情况下,许多连接显示为CLOSE_WAIT 我使用以下代码手动关闭连接:C++ 为什么在boost asio应用程序中导致许多关闭等待?,c++,sockets,boost,boost-asio,C++,Sockets,Boost,Boost Asio,几天前我发布了一个问题, 我还以为问题解决了 但事实并非如此,今天我有时可以重现错误。停止/启动连接到我的TCP服务器的2000个客户端应用程序后。在某些情况下,许多连接显示为CLOSE_WAIT 我使用以下代码手动关闭连接: void CloseSocket() { try { socket.shutdown(tcp::socket::shutdown_both); socket.close(); BOOST_LOG_TRIVIAL(warnin
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();
}
}
有些人说,不建议手动关闭插座,让asio为您完成。但有些人说,在关闭插座之前,应该先呼叫关机。我使用后一种方法,但问题仍然存在。关闭TCP连接时:
- 启动侧进入主动关闭。这将使启动器的连接进入
状态,防止地址被重新用作一种手段,以保证新连接不会接收到延迟数据包。该选项允许重新使用地址,即使连接处于TIME\u WAIT
状态。这通常用于允许服务器重新启动并立即开始侦听同一端口TIME\u WAIT
- 接收端进入被动关闭状态。接收器的连接将保持在
状态,直到插座关闭。当套接字关闭时,它允许释放回地址并由内核重用CLOSE\u WAIT
ClientType
聚合套接字,并且ClientType
实例由shared\u ptr
管理,可能永远不会删除ClientType
实例,因为套接字将在销毁期间关闭
另外,虽然
socket\u base::reuse\u address
不会影响CLOSE\u WAIT
,但使用它作为服务器的接受器仍然是一个好主意。最后,我解决了这个问题,因为我在启动服务器之前添加了这个命令
ulimit-n10240
谢谢大家。请使用非投掷过载,以确保您始终到达下一行。确保代码中的所有路径最终导致套接字关闭。我更改了代码,谢谢。摆脱关机。不管怎样,它都是作为关闭的一部分发生的。resue_地址选项有任何副作用吗?恢复的连接是否会收到延迟的数据包?据我所知,Asio上下文中的“自动关闭”通常意味着自动管理会话/套接字对象的寿命。在许多情况下,这确实是首选设计。@DeanChen对于Boost.Asio接收器(处于监听状态的套接字),它应该没有明显的副作用。对于其他情况,虽然可以接收前一个连接的数据包,就好像它们是当前连接的一部分一样,但不太可能。它要求在同一客户端启动具有相同地址、相同远程端口的新连接,并且延迟数据包的序列号与新连接上预期的协商序列号匹配后,才能接收到延迟数据包。@IgorR。谢谢你的更正。我忘记了当套接字的服务实现被破坏时,它会被关闭。绝对是首选设计。
acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));