聊天軟件中,輸入流和輸出流在同一個線程內應該獨立出來,彼此獨立(這就要引入多線程)
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(); } } }