有时候须要判断本地的某一个端口号是否被占用,网上通用的一种方法是:java
public boolean isPortAvailable(int port) { try { ServerSocket server = new ServerSocket(port); System.out.println("The port is available."); return true; } catch (IOException e) { System.out.println("The port is occupied."); } return false; }
经过新建一个ServerSocket来判断端口是否被占用,可是实际上这个检测方式是有漏洞的,有些状况不可以覆盖获得。例如,一个运行在WebLogic之上的应用它的端口为8406,则经过命令
linux
netstat -aon | findstr 8406
获得的结果可能为:bash
TCP 192.168.1.101:8406 111.111.111.111:80 SYN_SENT 112
可见8406绑定的内部IP地址为本机的IP地址192.168
.
1.101
,这时经过如上的方式获得的结果为这个端口没有被使用。缘由在于经过ServerSocket创建的链接绑定的IP为0.0.0.0,这一小小的差别致使了如上方法没有通用性,找到一种比较好的方法为:socket
private void bindPort(String host, int port) throws Exception { Socket s = new Socket(); s.bind(new InetSocketAddress(host, port)); s.close(); } public boolean isPortAvailable(int port) { Socket s = new Socket(); try { bindPort("0.0.0.0", port); bindPort(InetAddress.getLocalHost().getHostAddress(), port); return true; } catch (Exception e) { return false; } }
经过一个socket分别尝试去绑定0.0.0.0和本机IP上的port,当这两个port均可以被绑定时,则这个端口真的没有被占用。在linux上这一方法一样适用,可是有一种状况须要注意,当本机经过hostname不能解析到本机的IP地址时InetAddress.getLocalHost().getHostAddress()
这个函数会抛错,致使从结果来看端口被占用着。所以须要确保在/etc/hosts文件中存在着这么一条映射:ide
<hostname> <local_ip>
<hostname>为你在终端执行hostname返回的本机名,<local_ip>则为在终端执行ifconfig获得的本机真实IP,JAVA提供的这个函数会去这个文件中找<hostname>对应的IP地址,否则会由于找不到而抛错。确保这一条以后,在linux上也能正确检测指定端口的占用状况~
函数