基於TCP協議的socket編程實現簡單聊天室——羣聊

前言

上篇文章講了多線程的客戶端,本節需要在上篇文章的代碼的基礎上進行編寫。下面講解服務器實現一個客戶端發送其他除自己外的客戶端都能收到消息
文章鏈接
https://blog.csdn.net/qq_34963264/article/details/105042148

多線程類

/**
 * @author gaozhihao
 * @date 2020/3/23 0:31
 */
public class MyThread implements Runnable{
	//輸入數據流
    private DataInputStream dataInputStream;
    //轉發的數據流
    private DataOutputStream dataOutputStream;
    private Boolean flag = true;

	//初始化
    public MyThread(Socket socket){
        try {
            dataInputStream = new DataInputStream(socket.getInputStream());
            dataOutputStream = new DataOutputStream(socket.getOutputStream());
        } catch (IOException e) {
            flag = false;
            if (dataOutputStream != null){
                CloseUtil.closeAll(dataInputStream,dataOutputStream);
            }

        }
    }
	//獲取鍵盤鍵入的數據
    private String getMessage(){
        String str = "";
        try {
            str = dataInputStream.readUTF();
            System.out.println(str);
        } catch (IOException e) {
            e.printStackTrace();
            ServerTest3.list.remove(this);
        }
        return str;
    }
	//send暫時不用,使用轉發的方法
    private void send(String string){
        try {
            if (string != null && string.length() != 0){
                dataOutputStream.writeUTF(string);
                dataOutputStream.flush();
            }
        } catch (IOException e) {
            flag = false;
            CloseUtil.closeAll(dataOutputStream);
            ServerTest3.list.remove(this);

        }
    }

    //轉發數據
    private void otherSend(){
        String string = this.getMessage();
        //使用list集合保存其他已連接的客戶端,除了自己
        for (MyThread list :ServerTest3.list){
            if (this == list){
                continue;//不轉發到自己
            }
            //發送消息
            list.send(string);
        }
    }

    @Override
    public void run() {
        while (flag){
           // this.send(getMessage());
			//調用轉發方法
            this.otherSend();
        }
    }
}

服務器端

使用ArrayList存儲已連接的客戶端。


/**
 * @author gaozhihao
 * @date 2020/3/22 21:19
 */
public class ServerTest3 {
    //創建集合對象,存儲進來的客戶端
    public static List<MyThread> list = new ArrayList<>();

    public static void main(String[] args) throws IOException {
        System.out.println("------------------服務端開啓-----------------------");
        //創建ServerSocket對象
        ServerSocket serverSocket = new ServerSocket(9999);
        //監聽是否有客戶端連接
        while (true) {
            Socket client = serverSocket.accept();
            MyThread myThread = new MyThread(client);
            list.add(myThread);
            new Thread(myThread).start();
        }


    }
}

客戶端

代碼不變


/**
 * @author gaozhihao
 * @date 2020/3/22 21:33
 */
public class ClientTest3 {

    public static void main(String[] args) throws IOException {
        InetAddress inetAddress = InetAddress.getLocalHost();

        //創建socket對象
        Socket client = new Socket( inetAddress.getHostAddress(),9999);

        new Thread(new Send(client)).start();
        new Thread(new Receive(client)).start();
    }


}

運行效果

客戶端2輸入ok,自己沒有收到

客戶端3收到ok

服務器收到兩個客戶端發送的數據
**

注:客戶端3發送時,客戶端2沒有啓動,所以沒有收到hell數據。

**

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