Я пытался разрешить tcp-серверу связываться с портом close_wait, но это вызвало ошибку Errno::EADDRINUSE
.
Я создал tcp сервер, который прослушивает порт 55555. Затем клиент подключился к этому серверу. После нескольких операций запустите 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
Я пытался привязать порт 16413
, это вызвало ошибку Errno::EADDRINUSE
.
Но если я подключился к ESTAB-сокету, он мог привязаться к порту (например, 22385 ниже).
# 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
Некоторые сценарии ruby для воспроизведения проблемы.
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))
Создать close_wait
bind.
пробег ruby tcp_server_close_wait.rb
пробег ruby tcp_client.rb
запустите ss -at | grep 55555
, чтобы найти клиентский порт
пробег ruby tcp_bind.rb $client_port
Создать ESTAB
bind.
1. запустить ruby tcp_server.rb
пробег ruby tcp_client.rb
запустите ss -at | grep 55555
, чтобы найти клиентский порт
пробег ruby tcp_bind.rb $client_port