迭代器的方式会产生锁定
服务器端增加发送给每个客户端已收到信息的功能
所以当获取到一个socket,并打开它的线程进行循环接收客户端发来信息时,我们把这个内部类的线程Client保存到集合List<Client>中
然后在读取到客户端信息后,把这个信息发送给所有端口
通过循环
for(int i=0;i<clients.size();i++){
Client c=clients.get(i);
c.send(str);
}
发送给每一个已经成功连接到服务端的客户端
服务端详细的代码修改如下:
package com.swift; 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.Iterator; import java.util.List; public class ChatServer { boolean started = false; ServerSocket ss = null; Socket s = null; List<Client> clients=new ArrayList<Client>(); public static void main(String[] args) { new ChatServer().fun(); } private void fun() { try { ss = new ServerSocket(8888); started = true; } catch (BindException e) { System.out.println("端口使用中......"); } catch (IOException e1) { e1.printStackTrace(); } try { while (started) { s = ss.accept(); System.out.println("a client connected success"); Client c = new Client(s); new Thread(c).start(); clients.add(c); } } catch (EOFException e) { System.out.println("client has closed."); } catch (Exception e) { e.printStackTrace(); } finally { try { ss.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class Client implements Runnable { private Socket s; private DataInputStream dis; private DataOutputStream dos; private boolean connected = false; public Client(Socket s) { this.s = s; try { this.dis = new DataInputStream(s.getInputStream()); this.dos = new DataOutputStream(s.getOutputStream()); connected = true; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void send(String str) { try { dos.writeUTF(str); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }; } @Override public void run() { try {//注意:要包括while循环,如果try在while循环里,则出现socket closed异常 while (connected) { String str = dis.readUTF(); System.out.println(str); for(int i=0;i<clients.size();i++) { Client c=clients.get(i); c.send(str); } // for(Iterator<Client> 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 (IOException e) { e.printStackTrace(); } finally { if (dis != null) { try { dis.close(); } catch (IOException e) { e.printStackTrace(); } } if (s != null) { try { s.close(); } catch (IOException e) { e.printStackTrace(); } } if(dos!=null) { try { dos.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }