標籤:thread 逾時 外部 問題 exit write ann rac 用戶端串連
參考資料:Java核心技術 卷II
1. 使用Telent工具串連到伺服器
開啟Telnet:電腦右鍵,選擇屬性->控制台首頁->程式->開啟或關閉Windows功能,在彈出的視窗中選擇Telnet用戶端。
cmd開啟命令列視窗,
方法一:輸入:
telnet time-A.timefreq.bldrdoc.gov 13
方法二:
首先在命令窗中輸入:telnet,再在彈出的Telnet視窗中輸入:
o time-A.timefreq.bldrdoc.gov 13
結果為:
說明已經串連到了大多數UNIX電腦都支援的“當日時間”服務。按照慣例,“當日時間”服務總是串連到連接埠13.
下面的java實現與使用Telnet工具是一致的,即串連到某個連接埠並列印它所找到的資訊。
public class SocketTest { public static void main(String[] args) { // TODO Auto-generated method stub try{ Socket s = new Socket("time-A.timefreq.bldrdoc.gov", 13);//開啟一個通訊端 s.setSoTimeout(1000);//通訊端逾時設定 try{ InputStream inStream = s.getInputStream();//返回此通訊端的輸入資料流 Scanner in = new Scanner(inStream);//擷取流中的資料 while(in.hasNextLine()){//輸出資料流中的資料 String line = in.nextLine(); System.out.println(line); } } catch(InterruptedIOException exception){//擷取逾時異常 exception.printStackTrace(); } finally{ s.close();//關閉此通訊端 } } catch(IOException e){ e.printStackTrace(); } }}
2. 擷取IP地址
下面的java代碼擷取主機的IP地址。如果指定了主機名稱,將列印出給定主機的IP地址;如果沒有指定主機,則列印出本地主機的IP地址。
可在Run->Run Configurations->Arguments->Program arguments中,設定給定的主機名稱。設定好後,點擊apply->run.
public class InetAddressTest { public static void main(String[] args) { // TODO Auto-generated method stub try{ if(args.length > 0){//擷取從外部輸入的主機名稱 String host = args[0]; /** * static InetAddress getByName(String host)方法: 返回給定主機的IP地址 * static InetAddress getAllByName(String host)方法:返回給定主機所對應的所有IP地址組成的數組 */ InetAddress[] addresses = InetAddress.getAllByName(host); for(InetAddress a : addresses) System.out.println(a); } else{ //static InetAddress getLocalHost() 返回本地主機 InetAddress localHostAddress = InetAddress.getLocalHost(); System.out.println(localHostAddress); //byte[] getAddress() 返回此InetAddress對象的原始IP地址(byte數組形式) byte[] addressByte = localHostAddress.getAddress(); System.out.println(addressByte); //String getHostAddress() 返回字串形式的IP地址 String addressInte = localHostAddress.getHostAddress(); System.out.println(addressInte); //String getHostName() 返回主機名稱 String localHostName = localHostAddress.getHostName(); System.out.println(localHostName); } } catch(Exception e){ e.printStackTrace(); } }
3. 實現伺服器
實現一個簡單的伺服器,它可以向用戶端發送訊息。一旦啟動伺服器程式,它就等待某個用戶端串連到它的連接埠。這裡選擇的連接埠是8189. java實現:
public class EchoServer { public static void main(String[] args) { // TODO Auto-generated method stub try{ ServerSocket s = new ServerSocket(8189);// /建立一個負責監控8189連接埠的伺服器 Socket incoming = s.accept();//一旦用戶端向該連接埠發送了正確的串連請求,該方法就返回一個表示串連已經建立的Socket對象,可以用這個對象來得到輸入資料流和輸出資料流 try{ InputStream inStream = incoming.getInputStream(); //用於得到伺服器的輸入資料流 OutputStream outStream = incoming.getOutputStream();//用於得到伺服器的輸出資料流 Scanner in = new Scanner(inStream);//將伺服器的輸入資料流轉換成掃描器 PrintWriter out = new PrintWriter(outStream, true /* autoFlush */);//將伺服器的輸出資料流轉換成寫入器 out.println("Hello, Enter BYE to exit."); //給用戶端發送一條問候資訊 boolean done = false; while(!done && in.hasNextLine()){ String line = in.nextLine();//得到用戶端的輸入資料流 out.println("Echo: " + line);//用戶端的輸出資料流 if(line.trim().equals("BYE"))//當用戶端輸入為BYE時,退出 done = true; } } finally{ incoming.close();//關閉串連進來的通訊端 } } catch(IOException e){ e.printStackTrace(); } }}
運行:點擊運行,再在命令列視窗輸入:
telnet localhost 8189 //或telnet 127.0.0.1 8189
4. 為多個用戶端服務
利用線程解決多個用戶端同時串連到伺服器的問題。每當程式建立一個新的通訊端串連,即成功調用accept()方法的時候,將建立一個新的線程來處理伺服器和該用戶端之間的串連,而主程式將立即返回並等待下一個串連。java實現:
public class ThreadedEchoServer { public static void main(String[] args) { // TODO Auto-generated method stub try{ int i = 1; ServerSocket s = new ServerSocket(8189); while(true){//多個用戶端 Socket incoming = s.accept(); System.out.println("spawning " + i); //在伺服器端的輸出。 Runnable r = new ThreadedEchoHandler(incoming); Thread t = new Thread(r);//建立一個線程 t.start(); i++; } } catch(IOException e){ e.printStackTrace(); } }}/* * 實現Runnable介面的run 方法。 */class ThreadedEchoHandler implements Runnable{ private Socket incoming; public ThreadedEchoHandler(Socket i){ incoming = i; } public void run() { // TODO Auto-generated method stub try{ try{ InputStream inStream = incoming.getInputStream(); OutputStream outStream = incoming.getOutputStream(); Scanner in = new Scanner(inStream); PrintWriter out = new PrintWriter(outStream, true /* autoFlush */); out.println("Hello! Enter BYE to exit"); boolean done = false; while(!done && in.hasNextLine()){ String line = in.nextLine(); out.println("echo: " + line); if(line.trim().equals("BYE")) done = true; } } finally{ incoming.close(); } } catch(IOException e){ e.printStackTrace(); } }}
運行結果:可開啟多個Telnet視窗,並在這些視窗之間切換輸入資訊。
java網路編程(一)