java在线聊天项目0.8版 实现把服务端接收到的信息返回给每一个客户端窗口中显示功能

时间:2022-10-30 19:15:49

迭代器的方式会产生锁定

服务器端增加发送给每个客户端已收到信息的功能

所以当获取到一个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();
}
}
}

}

}
}