簡體   English   中英

Linux TCP服務器無法綁定到close_wait端口

[英]Linux tcp server can't bind to a close_wait port

我試圖讓tcp服務器綁定到close_wait端口,但是它導致了Errno::EADDRINUSE錯誤。

我創建了一個偵聽端口55555的tcp服務器。然后,客戶端連接到該服務器。 經過一些操作后,運行ss -at | grep 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綁定。

  1. 運行ruby tcp_server_close_wait.rb

  2. 運行ruby tcp_client.rb

  3. 運行ss -at | grep 55555 ss -at | grep 55555查找客戶端端口

  4. 運行ruby tcp_bind.rb $client_port

創建ESTAB綁定。 1.運行ruby tcp_server.rb

  1. 運行ruby tcp_client.rb

  2. 運行ss -at | grep 55555 ss -at | grep 55555查找客戶端端口

  3. 運行ruby tcp_bind.rb $client_port

我使用C程序對Linux 4.4.74-18.20重復了相同的測試。

我得到的結果與OP不同。

禁用SO_REUSEPORT時,兩個端口的綁定均失敗:

  • 建立的TCP連接的客戶端端口(ESTAB)
  • 半開TCP連接的客戶端端口(CLOSE-WAIT)

啟用S​​O_REUSEPORT(針對所有套接字)后,兩個端口的綁定成功。

有關獲得有關SO_REUSEPORT的更多信息,請參見socket(7)手冊頁

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM