在Java套接字编程中管理所有传入的聊天消息

时间:2018-02-07 01:57:25

标签: java sockets tcp serversocket

我正在开发一个具有聊天功能的程序,我正在使用套接字。 在我的情况下,我想在不同的窗口聊天中处理每个客户端(请查看附加图像)。

截至目前,当连接1个客户端时,没有问题。但是当连接2个客户端时,第一个客户端将被第二个客户端覆盖,除非我关闭连接的最新客户端的连接,否则他无法从服务器接收消息(服务器仍然接收来自所有客户端的消息,尽管只有一个客户端可以从服务器接收。)

我该怎么做?我正在使用队长casa框架 我想像下面的图像那样管理它。

IMAGE HERE

这是我的代码: 服务器:

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);
    }

1 个答案:

答案 0 :(得分:0)

我相信我理解这个问题,以及如何纠正它。

您正在为每个新连接使用唯一的线程(chatHandler) 该线程写一个自动" Hello"在连接时,但此后专门用于阅读消息(在while循环中你只读取din)并相应地更新控制台。由于每个线程都在管理对din的引用,因此所有传入的消息都可以。

但是,回写到客户端(serverSend)似乎不在线程中;它由按钮事件触发。此时,dout将是对最近连接的引用,而不是对要获取消息的客户端的引用。这就是最近的客户获得所有未来消息的原因。

更正是选择正确的' dout'为目标客户。当服务器'运营商'选择回信息(点击发送按钮),不知怎的,你需要获得正确的' dout'为那个客户。

这样做的一种方法是在创建线程之前建立dout(使用套接字),并维护每个客户端之间的关系,以及它对应的dout(即在Map中)。

如果问题仍然不明确(每个客户必须对dout有唯一的引用),请告诉我,我会尽力澄清。

相关问题