当服务器收到来自一个客户端的消息后,群发给所有的客户端!
服务器主动下推!
1服务器具有客户端列表,clientPoolr
2客户端必须创建一个子线程,不断接收服务器下发的消息
//和指定客户端对话线程
class ClientChatThread extends Thread{
private Socket client;
public ClientChatThread(Socket client) {
super();
this.client = client;
}
//将消息群发给所有人
private void sendAll(String str){
for(ClientChatThread ct:CustomThreadPoolAutoReplyTcpServer.pool){
try {
DataOutputStream dos = new DataOutputStream(ct.client.getOutputStream());
dos.writeUTF(str);
} catch (Exception e) {
System.out.println("发送给客户端["+ct.client.getPort()+"]失败,有可能断开了");
}
}
}
//和一个客户端对话的过程
@Override
public void run() {
try {
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
DataInputStream dis = new DataInputStream(client.getInputStream());
while (true) {
//加try是为了防止,客户端断开连接出现异常
try {
// 用这个流去封装输入流
String str = dis.readUTF();// 直接读取字符串
System.out.println(str);
//将群发消息发给线程中的所有客户端
// 把数据群发过去
sendAll(str);
} catch (Exception e) {
System.out.println("与客户端[" + client.getPort() + "]断开连接");
//删除不能连接的线程
CustomThreadPoolAutoReplyTcpServer.pool.remove(this);
System.out.println("客户端连接数:"+CustomThreadPoolAutoReplyTcpServer.pool.size());
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
//自定义线程池实现客户端多线程自动回复
public class CustomThreadPoolAutoReplyTcpServer {
public static Vector<ClientChatThread> pool=new Vector<>();//线程池,全局唯一
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(6667);
System.out.println("服务器端在6666端口启动成功,等待客户端连接...");
while (true) {
// 启动监听
Socket client = ss.accept();
System.out.println("客户端[" + client.getPort() + "]连接成功");
ClientChatThread ct=new ClientChatThread(client);
pool.add(ct);//放到线程池中
System.out.println("客户端连接数:"+pool.size());
ct.start();//启动线程
}
}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
class ReceiverServerThread extends Thread{
private Socket client;
public ReceiverServerThread(Socket client) {
super();
this.client = client;
}
@Override
public void run() {
DataInputStream dis =null;
try {
dis = new DataInputStream(client.getInputStream());
} catch (Exception e) {
e.printStackTrace();
return;
}
while(true){
String response;
try {
response = dis.readUTF();
System.out.println(response);//读取服务器内容
} catch (IOException e) {
System.out.println("被服务器断开连接了!");
return;
}
}
}
}
public class MultiplyPeopleTcpClient {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("请输入用户名:");
Scanner sc=new Scanner(System.in);
String name=sc.nextLine();
Socket client=new Socket("127.0.0.1",6667);
System.out.println("连接服务器127.0.0.1成功");
//创建线程不断接收服务的信息
new ReceiverServerThread(client).start();
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
String str="";
while(!"quit".equals(str=sc.nextLine())){
dos.writeUTF(name+":"+str);//将控制台内容写入服务器中
}
client.close();//断开服务器的连接
}
}