利用多線程實現聊天室的功能

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章