隨筆 -- IO -- Socket/ServerSocket -- 系統概述html
Java中提供的專門的網絡開發程序包------java.netjava
Java的網絡編程提供的兩種通訊協議:TCP和UDP編程
19.1 IP與InetAddress服務器
19.1.1 IP地址簡介網絡
19.1.2 InetAddress多線程
InetAddress類主要表示IP地址,這個類有兩個子類:Inet4Address、Inet6Address。app
InetAddress類的經常使用方法:socket
⊙ public static InetAddress getByName(String host)throws UnknownHostException :經過主機名稱獲得InetAddress對象post
⊙ public static InetAddress getLocalHost() throws UnknownHostException : 經過本機獲得InetAddress對象this
⊙ public String getHostName() : 獲得IP地址
⊙ public boolean isReachable(int timeout)throws IOException : 判斷地址是否能夠到達,同時指定超時時間。
package java_.net_.demo.java_15_5; import java.net.InetAddress; import java.net.UnknownHostException; public class InetAddressMain { public static void main(String[] args) throws Exception { InetAddress locAdd = null; InetAddress remAdd = null; locAdd = InetAddress.getLocalHost(); remAdd = InetAddress.getByName("www.baidu.com"); System.out.println("本機名稱 :" + locAdd.getHostName()); System.out.println("本機IP地址 :" + locAdd.getHostAddress()); System.out.println("百度IP地址 :" + remAdd); System.out.println("本機是否可達 :" + locAdd.isReachable(5000)); System.out.println("百度是否可達 :" + remAdd.isReachable(5000)); } }
19.2 URL與URLConnection
19.2.1 URL
URL統一資源定位符,能夠直接使用此類找到互聯網上的資源(如一個簡單的網頁)。
URL類的經常使用方法:
⊙ public URL(String spec) throws MalformedURLException : 根據指定的地址實例化URL對象。
⊙ public URL(String protocal,String host,int port,String file) throws MalformedURLException : 實例化URL對象,並指定協議、主機、端口名稱、資源文件。
⊙ public URLConnection openConnection() throws IOException : 取得一個URLConnection對象。
⊙ public final InputStream openStream() throws IOException : 取得輸入流。
package java_.net_.demo.java_15_5.URL_; import java.io.InputStream; import java.net.URL; import java.util.Scanner; public class URLMain { public static void main(String[] args) throws Exception{ URL url = new URL("http","www.mldnjava.cn",80,"/curriculum.htm"); InputStream input = url.openStream(); Scanner sc = new Scanner(input); sc.useDelimiter("\n"); while(sc.hasNext()){ System.out.println(sc.next()); } } }
19.2.2 URLConnection
URLConnection是封裝訪問遠程網絡資源通常方法的類,經過它能夠創建與遠程服務器的鏈接,檢查遠程資源的一些屬性。
此類的經常使用方法:
⊙ public int getContentLength() : 取得內容的長度。
⊙ public String getContentType() : 取得內容的類型。
⊙ public InputStream getInputStream() throws IOException : 取得鏈接的輸入流。
URLConnection對象能夠經過URL實例的openConnection()方法取得。
package java_.net_.demo.java_15_5.URLConnection; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.util.Scanner; public class URLConnectionMain { public static void main(String[] args) throws Exception{ URL url = new URL("http://www.mldnjava.cn"); URLConnection urlCon = url.openConnection(); System.out.println("內容大小 :" + urlCon.getContentLength()); System.out.println("內容類型 :" + urlCon.getContentType()); InputStream input = urlCon.getInputStream(); Scanner sc = new Scanner(input); sc.useDelimiter("\n"); while (sc.hasNext()) { System.out.println(sc.next()); } } }
19.3 URLEncoder 與 URLDecoder
在Java中若是要完成編碼和解碼操做就必須使用URLEncoder 和 URLDecoder兩個類。
URLEncoder 能夠爲傳遞的內容進行編碼;URLDecoder能夠爲傳遞的內容進行解碼。
URLEncoder類經常使用的方法:
⊙ public static Spring encode(String s,String enc) throws UnsupportedEncodingException : 使用指定的編碼機制將字符串轉換爲application/x-www-form-urlencoded格式。
URLDecoder類的經常使用方法:
⊙ public static Spring decode(String s,String enc) throws UnsupportedEncodingException : 使用指定的編碼機制對application/x-www-form-urlencoded字符串解碼。
package java_.net_.demo.java_15_5.URLEncoder; import java.net.URLDecoder; import java.net.URLEncoder; public class URLEncoderMain { public static void main(String[] args) throws Exception{ String keyWord = "lime甲骨文"; String encod = URLEncoder.encode(keyWord, "UTF-8"); System.out.println("編碼以後的內容 : " + encod); String decod = URLDecoder.decode(encod, "UTF-8"); System.out.println("解碼以後的內容 : " + decod); } }
19.4 TCP程序設計
在Java中使用Socket(即套接字)完成TCP程序的開發,使用此類能夠方便地簡歷可靠的、雙向的、持續的、點對點的通訊鏈接。
在Socket的程序開發中,服務器端使用ServerSocket等待客戶端鏈接,對於Java的網絡程序來說,每個客戶端都使用Socket對象表示。
19.4.1 ServerSocket 類與 Socket 類
ServerSocket主要用在服務器端程序的開發上,用於接收客戶端的鏈接請求。
ServerSocket類的經常使用方法:
⊙ public ServerSocket(int port)throws IOException : 建立ServerSocket實例,並指定監聽端口。
⊙ public Socket accept() throws IOException : 等待客戶端鏈接,此方法鏈接以前一直阻塞。
⊙ public InetAddress getInetAddress() : 返回服務器的IP地址。
⊙ public boolean isClosed() : 返回ServerSocket的關閉狀態。
⊙ public void close() throws IOException : 關閉ServerSocket。
在服務器端每次運行時都要使用accept()方法等待客戶端鏈接,此方法執行以後服務器端將進入阻塞狀態,知道客戶端鏈接以後程序能夠向下繼續執行。此方法返回值類型是Socket,每個Socket都表示一個客戶端對象。
Socket類的經常使用方法:
⊙ public Socket(String host,int port) throws UnknownHostException,IOException : 構造Socket對象,同時指定要鏈接服務器的主機名稱及鏈接端口。
⊙ public InputStream getInputStream() throws IOException : 返回此套接字的輸入流。
⊙ public OutputStream getOutputStream() throws IOException : 返回此套接字的輸入流。
⊙ public void close() throws IOException : 關閉此Socket。
⊙ public boolean isClosed() : 判斷此套接字是否被關閉。
在客戶端,程序能夠經過Socket類的getInputStream()方法取得服務器的輸入信息,在服務器端能夠經過getOutputStream()方法取得客戶端的輸出信息。
19.4.2 第一個TCP程序
Class : ServerSocketMain
package java_.net_.demo.java_15_5.serverSocket; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.util.Date; public class ServerSocketMain { public static void main(String[] args) throws Exception{ ServerSocket server = new ServerSocket(8888); Socket client = null; PrintStream out = null; int count = 1; while(true){ System.out.println("等待第 " + count + " 個客戶端接入"); client = server.accept(); System.out.println("第 " + count + " 個客戶端已接入"); count++; String resp = "Now is : " + new Date(); out = new PrintStream(client.getOutputStream()); out.println(resp); } } }
Class : SocketMain
package java_.net_.demo.java_15_5.socket; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.Socket; public class SocketMain { public static void main(String[] args) throws Exception{ Socket client = new Socket("localhost",8888); BufferedReader buf = null; buf = new BufferedReader(new InputStreamReader(client.getInputStream())); String str = buf.readLine(); System.out.println("服務器端輸出內容 :" + str); client.close(); buf.close(); } }
19.4.3 案例:Echo程序(BIO)
Echo程序是一個網絡編程通訊交互的一個經典案例,稱爲迴應程序,即客戶端輸入那些內容,服務器端會在這些內容前加上「ECHO:」並將信息發回客戶端。
本程序中將經過循環的方式使用accept(),這樣,每個客戶端執行完畢後,服務器端均可以從新等待用戶鏈接。
Class : EchoServer
package limeNet.server; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; public class EchoServer { public static void main(String[] args) throws Exception { ServerSocket server = null; Socket client = null; PrintStream out = null; BufferedReader buf = null; server = new ServerSocket(8888); boolean f = true; while(f){ System.out.println("服務器運行,等待客戶端鏈接。"); client = server.accept(); buf = new BufferedReader(new InputStreamReader(client.getInputStream())); out = new PrintStream(client.getOutputStream()); boolean flag = true; while(flag){ String str = buf.readLine(); if(null == str || "".equals(str)){ flag = false; }else{ if("bye".equals(str)){ flag = false; }else{ out.print("ECHO : " + str); } } } out.close(); buf.close(); client.close(); } server.close(); } }
Class : EchoClient
package limeNet.client; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; public class EchoClient { public static void main(String[] args) throws Exception, Exception { Socket client = null; client = new Socket("localhost",8888); BufferedReader input = null; PrintStream out = null; BufferedReader buf = null; input = new BufferedReader(new InputStreamReader(System.in)); out = new PrintStream(client.getOutputStream()); buf = new BufferedReader(new InputStreamReader(client.getInputStream())); boolean flag = true; while(flag){ System.out.print("輸入信息:"); String str = input.readLine(); out.print(str); if("bye".equals(str)){ flag = false; }else{ String echo = buf.readLine(); System.out.println(echo); } } client.close(); buf.close(); } }
19.4.4 在服務器上應用多線程
對於服務器端來講,若是要加入多線程機制,則應該在每一個用戶鏈接以後啓動一個新的線程。
Class : EchoThread
package limeNet.thread.server; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; public class EchoThread implements Runnable { private Socket accept; public EchoThread() { super(); } public EchoThread(Socket accept) { super(); this.accept = accept; } public void run() { DataInputStream in = null; DataOutputStream out = null; try { in = new DataInputStream(accept.getInputStream()); out = new DataOutputStream(accept.getOutputStream()); boolean goon = true; while (goon) { String str = in.readUTF(); if (null == str || "".equals(str)) { goon = false; } else { if ("bye".equalsIgnoreCase(str)) { goon = false; } else { out.writeUTF("ECHO:" + str); } } } in.close(); out.close(); accept.close(); } catch (IOException e) { e.printStackTrace(); } } }
Class : EchoThreadServer
package limeNet.thread.server; import java.net.ServerSocket; import java.net.Socket; public class EchoThreadServer { public static void main(String[] args) throws Exception { ServerSocket serverSocket = new ServerSocket(8888); while(true){ System.out.println("服務器運行,等待客戶端鏈接。"); Socket accept = serverSocket.accept(); new Thread(new EchoThread(accept)).start(); } } }
Class : EchoClient
package limeNet.client; import java.io.DataInputStream; import java.io.DataOutputStream; import java.net.Socket; import java.util.Scanner; public class EchoClient { public static void main(String[] args) throws Exception, Exception { Socket client = null; client = new Socket("localhost",8888); DataInputStream in = null; DataOutputStream out = null; in = new DataInputStream(client.getInputStream()); out = new DataOutputStream(client.getOutputStream()); Scanner sc = new Scanner(System.in); boolean flag = true; while(flag){ System.out.print("輸入信息:"); String str = sc.nextLine(); out.writeUTF(str); if("bye".equals(str)){ flag = false; }else{ String echo = in.readUTF(); System.out.println(echo); } } in.close(); out.close(); sc.close(); client.close(); } }
19.5 UDP程序設計
19.5.1 UDP簡介
19.5.2 UDP程序實現
Class : UDPClient
package limeNet.udp.client; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class UDPClient { public static void main(String[] args) throws IOException { DatagramSocket ds = new DatagramSocket(9000); byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, 1024); // 阻塞 ds.receive(dp); String str = new String(dp.getData(),0,dp.getLength()) + "from " + dp.getAddress().getHostAddress() + " : " + dp.getPort(); System.out.println(str); ds.close(); } }
Class : UDPServer
package limeNet.udp.server; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class UDPServer { public static void main(String[] args) throws IOException { DatagramSocket ds = null; DatagramPacket dp = null; ds = new DatagramSocket(3000); String str = "Hello World"; dp = new DatagramPacket(str.getBytes(), str.length(),InetAddress.getByName("localhost"),9000); System.out.println("發送信息。"); ds.send(dp); ds.close(); } }
啦啦啦
啦啦啦
啦啦啦
啦啦啦
啦啦啦
啦啦啦
啦啦啦
啦啦啦