當服務器收到來自一個客戶端的消息後,羣發給所有的客戶端!
服務器主動下推!
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();//斷開服務器的連接
}
}