Reputation: 3890
I posted one question a few days ago, why my app based on boost::asio didn't accept new connection And I thought it was solved.
But it is not, today I can reproduce the error sometimes. After stopping/starting the 2000 client apps which connect to my TCP server. In some cases, many connections are shown as CLOSE_WAIT.
I close the connection manually using below code:
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();
}
}
Also set address to be reused
acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
Some people said it's not recommended that closing the socket manually, let asio do it for you. But some people said you should call shutdown before close the socket. I use the latter way, but the problem still exists.
Upvotes: 4
Views: 2167
Reputation: 3890
Finally, I resolved this problem because I add this command before lauching the server
ulimit -n 10240
Thanks everyone.
Upvotes: 0
Reputation: 51891
When a TCP connection is being closed:
TIME_WAIT
state, preventing the address from being reused as a means to guarantee late packets are not received as part of a new connection. The socket_base::reuse_address
option allows for the address to be reused, even if the connection is in a TIME_WAIT
state. This is often used to allow a server to restart and immediately begin listening to the same port.CLOSE_WAIT
state until the socket has been closed. When the socket is closed, it allowing the address to be released back and reused by the kernel.As Igor R.'s succinctly suggest, the problem can be resolved by verifying that all paths allow for the socket to close. Based on your other question, given ClientType
aggregates socket, and ClientType
instances are managed by shared_ptr
, it may be possible that ClientType
instances are never being deleted, as the socket will close during its destruction.
Also, while socket_base::reuse_address
will not affect CLOSE_WAIT
, it may still be a good idea to use for the server's acceptor.
Upvotes: 3