本例只做簡易功能示範,代碼並不嚴謹,只是說明用戶端如何?串連服務端簡單代碼。
代碼在整合Eclipse工具下測試編譯運行環境如下圖所示:
用戶端echoClient.java代碼:
package com.zhengzz.echo;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;import java.net.UnknownHostException;class EchoC{ private Socket socket; public EchoC() { // TODO Auto-generated constructor stub try { socket = new Socket("localhost", 60000); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public void Client() { try { BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter pw = new PrintWriter(socket.getOutputStream(), true); BufferedReader lbr = new BufferedReader(new InputStreamReader(System.in)); String linestr = null; while ((linestr = lbr.readLine()) != null) { pw.println(linestr); System.out.println(br.readLine()); if (linestr.equals("bye#")) { break; } } } catch (IOException e) { e.printStackTrace(); } }}public class echoClient { public static void main(String[] args) { new EchoC().Client(); }}
服務端echoServer.java代碼:
package com.zhengzz.echo;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;class EchoS{ private ServerSocket serverSocket; public EchoS() { try { serverSocket = new ServerSocket(60000); } catch (IOException e) { e.printStackTrace(); } } public void Server() { while (true) { try { Socket socket = serverSocket.accept(); System.out.println("client:" + socket.getInetAddress() + ":" + socket.getLocalPort()); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter pw = new PrintWriter(socket.getOutputStream(), true); String linestr; while ((linestr = br.readLine()) != null) { System.out.println(linestr); pw.println("--->" + linestr); } } catch (IOException e) { System.out.println("串連斷開:("); } }}}public class echoServer { public static void main(String[] args) { new EchoS().Server(); }}
我在Eclipse工具下直接調試結果如下:
下面我們再來看一個 HelloWord 層級的 Java Socket 通訊的例子。通訊過程:
先啟動 Server 端,進入一個死迴圈以便一直監聽某連接埠是否有串連請求。然後運行 Client 端,用戶端發出串連請求,服務端監聽到這次請求後向用戶端發回接受訊息,串連建立,啟動一個線程去處理這次請求,然後繼續死迴圈監聽其他請求。用戶端輸入字串後按斷行符號鍵,向伺服器發送資料。伺服器讀取資料後回複用戶端資料。這次請求處理完畢,啟動的線程消亡。如果用戶端接收到 "OK" 之外的返回資料,會再次發送串連請求並發送資料,伺服器會為這次串連再次啟動一個線程來進行響應。。。直到當用戶端接收到的返回資料為 "OK" 時,用戶端退出。
服務端原始碼:
package com.defonds.socket.begin; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; public class Server { public static final int PORT = 12345;//監聽的連接埠號碼 public static void main(String[] args) { System.out.println("伺服器啟動...\n"); Server server = new Server(); server.init(); } public void init() { try { ServerSocket serverSocket = new ServerSocket(PORT); while (true) { // 一旦有堵塞, 則表示伺服器與用戶端獲得了串連 Socket client = serverSocket.accept(); // 處理這次串連 new HandlerThread(client); } } catch (Exception e) { System.out.println("伺服器異常: " + e.getMessage()); } } private class HandlerThread implements Runnable { private Socket socket; public HandlerThread(Socket client) { socket = client; new Thread(this).start(); } public void run() { try { // 讀取用戶端資料 DataInputStream input = new DataInputStream(socket.getInputStream()); String clientInputStr = input.readUTF();//這裡要注意和用戶端輸出資料流的寫方法對應,否則會拋 EOFException // 處理用戶端資料 System.out.println("用戶端發過來的內容:" + clientInputStr); // 向用戶端回複資訊 DataOutputStream out = new DataOutputStream(socket.getOutputStream()); System.out.print("請輸入:\t"); // 發送鍵盤輸入的一行 String s = new BufferedReader(new InputStreamReader(System.in)).readLine(); out.writeUTF(s); out.close(); input.close(); } catch (Exception e) { System.out.println("伺服器 run 異常: " + e.getMessage()); } finally { if (socket != null) { try { socket.close(); } catch (Exception e) { socket = null; System.out.println("服務端 finally 異常:" + e.getMessage()); } } } } } }
用戶端原始碼:
package com.defonds.socket.begin; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; public class Client { public static final String IP_ADDR = "localhost";//伺服器位址 public static final int PORT = 12345;//伺服器連接埠號碼 public static void main(String[] args) { System.out.println("用戶端啟動..."); System.out.println("當接收到伺服器端字元為 \"OK\" 的時候, 用戶端將終止\n"); while (true) { Socket socket = null; try { //建立一個流通訊端並將其串連到指定主機上的指定連接埠號碼 socket = new Socket(IP_ADDR, PORT); //讀取伺服器端資料 DataInputStream input = new DataInputStream(socket.getInputStream()); //向伺服器端發送資料 DataOutputStream out = new DataOutputStream(socket.getOutputStream()); System.out.print("請輸入: \t"); String str = new BufferedReader(new InputStreamReader(System.in)).readLine(); out.writeUTF(str); String ret = input.readUTF(); System.out.println("伺服器端返回過來的是: " + ret); // 如接收到 "OK" 則中斷連線 if ("OK".equals(ret)) { System.out.println("用戶端將關閉串連"); Thread.sleep(500); break; } out.close(); input.close(); } catch (Exception e) { System.out.println("用戶端異常:" + e.getMessage()); } finally { if (socket != null) { try { socket.close(); } catch (IOException e) { socket = null; System.out.println("用戶端 finally 異常:" + e.getMessage()); } } } } } }
注意: Socket 輸出資料流寫資料方法是 writeUTF 時,輸入資料流讀取相關資料要用 readUTF。否則會拋 EOFException 異常。