客户端为什么要引入多线程
聊天软件中,输入流和输出流在同一个线程内应该独立出来,彼此独立(这就要引入多线程)
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(); } } }