迭代器的方式會產生鎖定 伺服器端增加發送給每個客戶端已收到信息的功能 所以當獲取到一個socket,並打開它的線程進行迴圈接收客戶端發來信息時,我們把這個內部類的線程Client保存到集合List<Client>中 然後在讀取到客戶端信息後,把這個信息發送給所有埠 通過迴圈 for(int i=0 ...
迭代器的方式會產生鎖定
伺服器端增加發送給每個客戶端已收到信息的功能
所以當獲取到一個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(); } } } } } }