簡體   English   中英

在java socket編程中管理所有傳入的聊天消息

[英]Manage all incoming chat messages in java socket programming

我正在開發一個具有聊天功能的程序,我正在其中使用套接字。 就我而言,我想在不同的窗口聊天中處理每個客戶端(請參閱附加圖片)。

截至目前,當連接1個客戶端時,沒有問題。 但是當連接了 2 個客戶端時,第一個客戶端將被第二個覆蓋,除非我關閉最新連接的客戶端的連接,否則他無法從服務器接收消息(服務器仍然接收來自所有客戶端的消息,盡管只有 1 個客戶端可以從服務器接收)。

我要怎么做? 我正在使用船長 casa 框架,我想像下圖那樣管理它。

圖像在這里

這是我的代碼:服務器:

public void mainserver(){
        Thread server = new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    serverSocket = new ServerSocket(port);
                    System.out.println("Server Online... \nWaiting for Connections");
                } catch (IOException e) {
                    e.printStackTrace();
                }

                while (accept){
                    try {
                        socket = serverSocket.accept();
                        System.out.println("New Connection Estasblished!!!");

                        chatHandler chat = new chatHandler(socket);
                        chat.start();
                    } catch (IOException e) {
                        System.out.println("server not terminate all connections");
                        System.exit(-1);
                    }
                }
            }
        });
        server.start();
    }

public class chatHandler extends Thread{

       Socket socket;

       public chatHandler(Socket socket){
           this.socket = socket;
       }

       public void run(){
           try {
               din = new DataInputStream(socket.getInputStream());
               dout = new DataOutputStream(socket.getOutputStream());

               dout.writeUTF("Hi! Thank you for reaching us! How may I help you!?");

               while (!read.equals(".end")){

                   read = din.readUTF();

                   if (getServerArea()!=null){
                       setServerArea(getServerArea()+"\n"+read);
                   }else {
                       setServerArea(read);
                   }
               }
               System.out.println("end of chat server");
           } catch (IOException e) {
               e.printStackTrace();
           }finally {
               System.out.println("Exit");
               try {
                   dout.close();
                   din.close();
                   socket.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }

       }
   }

public void serverSend(javax.faces.event.ActionEvent event) { // "Send" button
        write = getServerField();
        try {
            dout.writeUTF(write);
            dout.flush();
            if (getServerArea()!=null){
                setServerArea(getServerArea()+"\n"+write);
                setServerField("");
            }else {
                setServerArea(write);
                setServerField("");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(write);
    }

客戶:

public void client(){
        Thread client = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    socket = new Socket("localhost",port);

                    din  = new DataInputStream(socket.getInputStream());
                    dout = new DataOutputStream(socket.getOutputStream());

                    while (!read.equals("bye")){
                        read = din.readUTF();

                        if (getClientArea()!=null){
                            setClientArea(getClientArea()+"\n"+read);
                        }else {
                            setClientArea(read);
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    try {
                        din.close();
                        dout.close();
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        client.start();
    }

    public void clientSend(javax.faces.event.ActionEvent event) {
        write = getClientField();
        try {
            dout.writeUTF(write);
            dout.flush();
            if (getClientArea()!=null){
                setClientArea(getClientArea()+"\n"+write);
                setClientField("");
            }else {
                setClientArea(write);
                setClientField("");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(write);
    }

我相信我理解這個問題,以及如何糾正它。

您為每個新連接使用唯一的線程 (chatHandler)。
該線程在連接時自動寫入“Hello”,但此后專門用於讀取消息(在 while 循環中您只讀取 din)並相應地更新控制台。 由於每個線程都在管理對 din 的引用,因此所有傳入的消息都可以。

但是,寫回客戶端(serverSend)似乎不在線程中; 它由按鈕事件觸發。 此時,dout 將是對最近連接的引用,而不是對打算獲取消息的客戶端的引用。 這就是為什么最近的客戶端會收到所有未來的消息。

更正是為目標客戶選擇正確的“dout”。 當服務器“操作員”選擇寫回消息(單擊發送按鈕)時,您需要以某種方式為該客戶端獲取正確的“dout”。

一種方法是在創建線程之前建立dout(使用socket),並維護每個客戶端之間的關系,以及它對應的dout(即在Map中)。

如果問題仍然不明確(每個客戶必須有一個唯一的 Dout 引用),請告訴我,我會盡力澄清。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM