有時候須要判斷本地的某一個端口號是否被佔用,網上通用的一種方法是: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上也能正確檢測指定端口的佔用狀況~
函數