用戶端為什麼要引入多線程,用戶端引入多線程
聊天軟體中,輸入資料流和輸出資料流在同一個線程內應該獨立出來,彼此獨立(這就要引入多線程)
package com.sxt.chat;import java.io.BufferedReader;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.net.Socket;import java.net.UnknownHostException;public class Test { public static void main(String[] args) throws UnknownHostException, IOException { Socket client = new Socket("localhost",8888); BufferedReader console = new BufferedReader(new InputStreamReader(System.in)); //輸入資料流(接收用戶端發送過來的) DataInputStream dis = new DataInputStream(client.getInputStream()); //輸出資料流(發送給用戶端) DataOutputStream dos = new DataOutputStream(client.getOutputStream()); while(true){ //給用戶端發送過去 String msg =console.readLine(); dos.writeUTF(msg); dos.flush(); //輸出用戶端發送過來的 String info = dis.readUTF(); System.out.println(info); } }}
從上面代碼中我們知道,先要從用戶端輸入資料,再接收伺服器端發送過來的資訊,而在我們聊天軟體中,接收資料和發送資料是獨立的,從而我們可以把上面代碼改成以下形式
package com.sxt.chat;import java.io.IOException;import java.net.Socket;import java.net.UnknownHostException;public class Client { public static void main(String[] args) throws UnknownHostException, IOException { Socket client = new Socket("localhost",8888); //一條路徑 new Thread(new Send(client)).start();; new Thread(new Receive(client)).start();; }}
發送資料的代碼如下:
package com.sxt.chat;import java.io.BufferedReader;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.net.Socket;public class Send implements Runnable{ //從控制台輸入 private BufferedReader console ; //輸出資料流(發送給伺服器端) private DataOutputStream dos ; //標誌位 private boolean isRunning = true; public Send(){ console = new BufferedReader(new InputStreamReader(System.in)); } public Send(Socket client){ this(); try { dos = new DataOutputStream(client.getOutputStream()); } catch (IOException e) { isRunning = false; CloseUtil.closeAll(dos,console); } } /* *從控制台接收資料 */ public String getMsgFromConsole(){ try { return console.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return ""; } /* *從控制台接收資料 */ public void send(){ String msg = getMsgFromConsole(); if(null!=msg&&!msg.equals("")){ try { dos.writeUTF(msg); dos.flush(); } catch (IOException e) { isRunning = false; CloseUtil.closeAll(dos,console); } } } @Override public void run() { while(isRunning){ send(); } }}
接收資料的代碼如下:
package com.sxt.chat;import java.io.DataInputStream;import java.io.IOException;import java.net.Socket;public class Receive implements Runnable{ //輸入資料流(接收伺服器端發送過來的) private DataInputStream dis ; //標誌符 private boolean isRunning = true; public Receive(){ } public Receive(Socket client){ this(); try { dis = new DataInputStream(client.getInputStream()); } catch (IOException e) { } } public String receive(){ String msg = ""; try { msg = dis.readUTF(); } catch (IOException e) { isRunning = false; CloseUtil.closeAll(dis); } return msg; } @Override public void run() { while(isRunning){ System.out.println(receive()); } }}
關閉流資料代碼如下:
package com.sxt.chat;import java.io.Closeable;import java.io.IOException;public class CloseUtil { public static void closeAll(Closeable... io){ for(Closeable temp :io){ if(null!=temp){ try { temp.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }}
伺服器代碼如下:
package com.sxt.chat;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;public class Server { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(8888); Socket client = server.accept(); //輸入資料流(接收用戶端發送過來的) DataInputStream dis = new DataInputStream(client.getInputStream()); //輸出資料流(發送給用戶端) DataOutputStream dos = new DataOutputStream(client.getOutputStream()); while(true){ //輸出用戶端發送過來的 String msg = dis.readUTF(); System.out.println(msg); //給用戶端發送過去 dos.writeUTF("伺服器===》"+msg); dos.flush(); } }}