我收到正在使用的端口无法在进程重新启动时绑定。我想知道何时考虑使用端口?
是只有在“LISTEN”模式下才会出现吗?如果端口打开的连接处于 TIME_WAIT 状态(或 TCP 中的任何其他状态),也可能如此吗?有限状态机)?
tcp 0 0 127.0.0.1:7199 0.0.0.0:* LISTEN 30099/java
tcp 0 0 192.168.1.2:9160 0.0.0.0:* LISTEN 30099/java
tcp 0 0 192.168.1.2:58263 192.168.1.2:9042 TIME_WAIT -
tcp 0 0 192.168.1.2:58262 192.168.1.2:9042 TIME_WAIT -
tcp 0 0 ::ffff:192.168.1.2:9042 :::* LISTEN 30099/java
tcp 0 0 ::ffff:192.168.1.2:9042 ::ffff:192.168.1.2:57191 ESTABLISHED 30099/java
tcp 0 0 ::ffff:192.168.1.2:9042 ::ffff:192.168.1.2:57190 ESTABLISHED 30099/java
tcp 0 0 ::ffff:192.168.1.2:9042 ::ffff:10.176.70.226:37105 ESTABLISHED 30099/java
tcp 0 0 ::ffff:127.0.0.1:42562 ::ffff:127.0.0.1:7199 TIME_WAIT -
tcp 0 0 ::ffff:192.168.1.2:57190 ::ffff:192.168.1.2:9042 ESTABLISHED 30138/java
tcp 0 0 ::ffff:192.168.1.2:57198 ::ffff:192.168.1.2:9042 ESTABLISHED 30138/java
tcp 0 0 ::ffff:192.168.1.2:9042 ::ffff:10.176.70.226:37106 ESTABLISHED 30099/java
tcp 0 0 ::ffff:192.168.1.2:57197 ::ffff:192.168.1.2:9042 ESTABLISHED 30138/java
tcp 0 0 ::ffff:192.168.1.2:57191 ::ffff:192.168.1.2:9042 ESTABLISHED 30138/java
tcp 0 0 ::ffff:192.168.1.2:9042 ::ffff:192.168.1.2:57198 ESTABLISHED 30099/java
tcp 0 0 ::ffff:192.168.1.2:9042 ::ffff:192.168.1.2:57197 ESTABLISHED 30099/java
tcp 0 0 ::ffff:127.0.0.1:42567 ::ffff:127.0.0.1:7199 TIME_WAIT -
该进程是一个公开 JMX 端口的 Java 进程。并且有一些监控代理向该端口发送请求以获取信息。我想确保重新启动时(停止后和启动前)端口是空闲的,因此不会遇到端口绑定问题。如果该端口上的待处理 TIME_WAIT 连接被视为正在使用的端口,那么我将在停止和启动之间添加等待,以便在进程启动之前清除这些 TIME_WAIT 状态。除非有其他更好的选择。
谢谢
答案1
只要有任何套接字绑定到某个端口,该端口就被视为“正在使用”。它们不必处于 LISTEN 状态,只需处于绑定状态即可。因此,您看到的 TIME_WAIT 套接字确实有效。
如果任何套接字绑定到地址,事情就会变得有点复杂和端口。如果不同的套接字绑定到不同的地址,则允许将它们绑定到同一端口。但是,如果有任何套接字绑定到该端口的通配符地址(INADDR_ANY
,显示为netstat
as *
),则会阻止其他套接字绑定到任何地址和相同的端口。
通常,大多数使用侦听套接字的软件都会SO_REUSEADDR
在这些套接字上设置套接字选项。此选项放宽了规则。通过设置选项,只有一个界限和侦听套接字可防止另一个套接字绑定到同一地址。这意味着任何延迟TIME_WAIT
和其他套接字都不会阻止软件重新启动并立即重新绑定到同一端口。
您的 Java 程序很可能没有设置SO_REUSEADDR
其套接字,但它应该设置。