上一版本,客户端关闭后会出现“socket close”异常问题,这个版本用捕捉异常来解决,实际上只是把异常输出的语句改为用户退出之类,并没真正解决
服务器类
package Chat03; /** * 相比01,加进了线程内部类,解决多个客户端连接时,服务器无法全部响应的问题。 * @author Administrator * */ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; public class ChatSever03 { // 布尔类型变量表示服务器是否开着 boolean started = false; ServerSocket ss = null; List<Client> clients = new ArrayList<Client>(); public static void main(String[] args) { new ChatSever03().start(); } public void start() { try { // 建立服务端,8888为端口号 ss = new ServerSocket(8888); started = true; } catch (BindException e) { System.out.println("Socket has been used !"); System.out.println("请重启服务器 !"); System.exit(0); }catch (IOException e) { e.printStackTrace(); } // 服务器开启后,started变为true try { // 接受客户端的连接 while (started) { Socket s = ss.accept(); //构造Client对象 Client c = new Client(s); clients.add(c); System.out.println("一个客户连接"); //启动线程 new Thread(c).start(); } } catch (Exception e) { e.printStackTrace(); } finally { try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 建立线程内部类 */ class Client implements Runnable{ //要保有自己的Socket属性 private Socket s = null; //自己的数据输入流 private DataInputStream dis = null; private DataOutputStream dos = null; private boolean bConnected = false ; //采用构造方法,把Socket属性传进来 public Client(Socket s) { //赋值给s this.s = s ; //将dis初始化 try { dis = new DataInputStream(s.getInputStream()); dos = new DataOutputStream(s.getOutputStream()); //连接成功后,bConnected 变为true bConnected = true ; } catch (IOException e) { e.printStackTrace(); } } /** * 发送信息的方法 */ public void send(String str) { try { dos.writeUTF(str); System.out.println(str); } catch (IOException e) { clients.remove(this); System.out.println("对方退出了"); //e.printStackTrace(); } } @Override public void run() { try { //while循环范围过大, 导致过一直报错; while (bConnected) { String str = dis.readUTF (); //System.out.println(str); //发送信息 for(int i = 0;i < clients.size(); i++) { Client c = clients.get(i); c.send(str); //System.out.println(str); } /*利用迭代器 for(Iterator it = clients.iterator();it.hasNext();) { Client c = it.next(); c.send(str); } */ /*利用迭代器第二版本 Iterator<Client> it = clients.iterator(); while(it.hasNext()) { Client c = it.next(); c.send(str); } */ } }catch (EOFException e) { System.out.println("Client Close !"); }catch (IOException e) { e.printStackTrace(); }finally { try { if(dis != null) dis.close(); //再设置dis = null; if(dos != null) dis.close(); if(s != null) s.close(); } catch (IOException e) { e.printStackTrace(); } } } } }