I tried to let tcp server bind to a close_wait port, but it caused a Errno::EADDRINUSE
error.
I created a tcp server that listen on port 55555. Then client connected to that server. After some ops, run ss -at | grep 55555
.
# ss -at | grep 55555
LISTEN 0 128 *:55555 *:*
FIN-WAIT-2 0 0 127.0.0.1:55555 127.0.0.1:16413
CLOSE-WAIT 0 0 127.0.0.1:16413 127.0.0.1:55555
I tried to bind port 16413
, it caused a Errno::EADDRINUSE
error.
But if I connected to a ESTAB socket, the socket could bind to the port(such as 22385 below).
# ss -at | grep 55555
LISTEN 0 128 *:55555 *:*
ESTAB 0 0 127.0.0.1:22385 127.0.0.1:55555
ESTAB 0 0 127.0.0.1:55555 127.0.0.1:22385
Some scripts by ruby to reproduce the problem.
tcp_server_close_wait.rb
require 'socket'
server = TCPServer.new 55555 # Server bind to port 2000
loop do
client = server.accept # Wait for a client to connect
client.puts "Hello !"
client.puts "Time is #{Time.now}"
client.shutdown(Socket::SHUT_WR)
end
tcp_server.rb
require 'socket'
server = TCPServer.new 55555 # Server bind to port 2000
loop do
client = server.accept # Wait for a client to connect
client.puts "Hello !"
client.puts "Time is #{Time.now}"
client.close
end
tcp_client.rb
require 'socket'
include Socket::Constants
socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
sockaddr = Socket.pack_sockaddr_in( 55555, '127.0.0.1' )
socket.connect( sockaddr )
res = socket.read
puts res
sleep 10000
** tcp_bind.rb **
require 'socket'
# use Addrinfo
socket = Socket.new(:INET, :STREAM, 0)
socket.bind(Addrinfo.tcp("0.0.0.0", ARGV[0].to_i))
Create close_wait
bind.
run
ruby tcp_server_close_wait.rb
run
ruby tcp_client.rb
run
ss -at | grep 55555
to find client portrun
ruby tcp_bind.rb $client_port
Create ESTAB
bind.
1. run ruby tcp_server.rb
run
ruby tcp_client.rb
run
ss -at | grep 55555
to find client portrun
ruby tcp_bind.rb $client_port
SO_REUSEADDR
socket option. – Some programmer dudeSO_REUSEADDR
has nothing to do with the problem. Every tcp server && client was created withoutSO_REUSEADDR
。 – AnienSO_REUSEADDR
is set on a socket in theTIME_WAIT
state, then another socket should be able to bind to the same address as the closing socket is/was bound to. – Some programmer dudeclose wait
can't be bind to, butESTAB
can be. – Anien