標籤:測試 資料 rgs pre while nts 通訊 解惑 htm
java在JDK1.5以前都是用java.nio包中的Ping類來實現ping。在JDK1.7版本的API文檔中就沒找到這個類了。
java.nio包是對非阻塞流IO進行處理,java.io包是對阻塞流IO進行處理。前幾天都是使用io阻塞流來實現用戶端與服務端的通訊。
在socket中,目前我知道的有兩個人方法可以阻塞程式,一個是輸入資料流InputStream的read方法,一個是ServerSocket中的accept
方法。C/S模式中有個弊端,當用戶端每次向服務端發送socket,服務端都會開啟一個線程來管理,那麼10000個用戶端,服務端
就需要開啟10000個線程,當用戶端數量較大的時候,阻塞流IO顯然不適合,那麼就要使用非阻塞流IO,如果有10000個用戶端,
服務端使用非阻塞IO流就只要1000個線程就可以完成管理,因為阻塞流IO是同步的,非阻塞流IO是非同步,更多的關於阻塞流IO
與非阻塞流IO的知識,我想我需要相關書籍進行學習。
那麼JAVA實現ping,可以調用WINDOS系統下的命令符ping來實現。代碼如下:
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.InetAddress;import java.net.UnknownHostException;public class Test { public static void ping(String host){ String line = null; try{ Process pro = Runtime.getRuntime().exec("ping " + host); BufferedReader buf = new BufferedReader(new InputStreamReader(pro.getInputStream(),"gbk")); while ((line = buf.readLine()) != null){ System.out.println(line); } }catch (Exception ex){ System.out.println(ex.getMessage()); } } /** * @param host */ public static void icmp(String host){ try { int timeOut = 3000; boolean status = InetAddress.getByName(host).isReachable(timeOut); System.out.println("發送資料包: " + status); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * @param args */ public static void main(String[] args) throws UnknownHostException { ping(InetAddress.getByName("www.baidu.com").getHostAddress()); icmp(InetAddress.getByName("www.baidu.com").getHostAddress()); }}
從代碼中可以看出,我是ping了百度的,百度發回來的報文是GBK格式的,不設定會出現亂碼現象,還有一個點是InetAddress包中的isReachable方法,這個方法在API文檔中描述是這樣的:
測試該地址是否可訪問。最好的實現是通過嘗試到達主機,但是防火牆和伺服器配置可能會阻塞導致不可到達狀態的請求,而某些特定連接埠可能是可訪問的。一個典型的實現將使用ICMP回聲請求,如果可以獲得特權,否則它將試圖在目標主機的連接埠7(回聲)上建立一個TCP串連。
逾時值(以毫秒為單位)表示嘗試應該佔用的最大時間。如果操作在獲得答案之前逾時,則主機被認為是不可到達的。負值將導致時拋出。
也就是說,這個方法基本上是使用目標主機的連接埠7建立TCP串連了,基本不關PING什麼事情。
附上JDK1.5版本以前的Ping類實現,有興趣的可以看看。
https://docs.oracle.com/javase/1.5.0/docs/guide/nio/example/index.html
java關於ping方面的解惑