Java 網絡編程--------------------基於TCP/IP(加入多線程)
1、服務器類:
package com.serversocket; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Server_02 { //定義保存所有Socket的ArrayList,並將其包裝爲線程安全的 public static List<Socket> socketList = Collections.synchronizedList(new ArrayList<>()); public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(30000); while(true){ //此行代碼會阻塞,會一直等待別人的鏈接 Socket s = ss.accept(); socketList.add(s); //每當客戶端連接成功後啓動一個ServerThread線程爲該客戶端服務 new Thread(new ServerThread02(s)).start(); } } }
2、服務器線程類
package com.serversocket; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; public class ServerThread02 implements Runnable { //定義當前線程處理的Socket Socket s = null; //該線程所處理的Socket的輸入流 BufferedReader br = null; public ServerThread02(Socket s) throws IOException { this.s = s; //初始化該Socket所對應的輸入流 br = new BufferedReader(new InputStreamReader(s.getInputStream())); } public void run() { try { String content = null; //採用循環不斷的從Socket中讀取客戶端發送過來的數據 while ((content = readFromClient()) != null) { //遍歷socketList中的每個Socket //將讀到的內容向每個Socket發送一次 for (Socket s : Server_02.socketList) { PrintStream ps = new PrintStream(s.getOutputStream()); ps.println(content); } } } catch (IOException e) { e.printStackTrace(); } } //定義讀取客戶端數據的方法 private String readFromClient() { try { return br.readLine(); //如果捕獲到異常,則表明Socket對應的客戶端已經關閉 } catch (IOException e) { //刪除該Socket Server_02.socketList.remove(s); } return null; } }
3、客戶端類
package com.socket; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; public class Client_02 { public static void main(String[] args) throws Exception { Socket s = new Socket("127.0.0.1",30000); //客戶端啓動ClientThread02不斷的讀取來自服務器的數據 new Thread(new ClientThread02(s)).start(); PrintStream ps = new PrintStream(s.getOutputStream()); String line = null; System.out.println("請輸入消息:"); //不斷讀取鍵盤的輸入 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); while((line = br.readLine())!=null){ //將用戶的鍵盤輸入內容寫入Socket對應的輸出流 ps.println(line); } } }
4、客戶端線程類
package com.socket; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; public class ClientThread02 implements Runnable { //該線程負責處理的Socket private Socket s = null; //該線程處理的Socket對應的輸入流 BufferedReader br = null; public ClientThread02(Socket s) throws IOException{ this.s = s; br = new BufferedReader(new InputStreamReader(s.getInputStream())); } @Override public void run() { try{ String content = null; //不斷讀取Socket輸入流中的內容,並將這些內容打印輸出 while((content=br.readLine()) != null){ System.out.println(content); } }catch(IOException e){ e.printStackTrace(); } } }
編寫好上面代碼之後,首先啓動服務器類,然後再啓動客戶端類(可以啓動多個客戶端類)