迭代器的方式会产生锁定
服务器端增加发送给每个客户端已收到信息的功能
所以当获取到一个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();
}
}
}
}
}
}