首页 > 解决方案 > 在 java 套接字编程聊天应用程序中,是否可以像 whatsapp 一样为每个客户端创建单独的聊天?

问题描述

现在我完成了具有服务器和客户端的应用程序,服务器接受客户端请求并将客户端对象添加到 Arraylist 并为每个客户端启动一个新线程。当多个客户端连接时,客户端可以列出所有客户端,并且可以向列表中的任何客户端发送消息。例如client1,client2,client3连接到服务器client1,client2向client3发送消息,会在client3控制台打印。一切正常。现在我需要添加每个客户端在单独聊天中发送消息的附加功能,如果客户端 1 打开与客户端 2 的聊天,则应该只显示这两个客户端之间的对话,而不是客户端 3 消息,反之亦然。要做到这一点,我需要任何额外的概念,比如多线程。我不是在问源代码,我'

谁能告诉我为不同客户实施单独聊天的建议或参考...需要保留旧消息直到服务器离线?

服务器.java

package server;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.*;
import java.util.Vector;

public class Server {
    static Vector<ClientHandler> AllClients = new Vector<ClientHandler>();
    public static void main(String args[]) throws Exception {

        try {
            ServerSocket ss = new ServerSocket(1111);
            System.out.println("Server Started");
            while(true) {
                Socket s = ss.accept();
                DataInputStream dis = new DataInputStream(s.getInputStream());
                String clientname = dis.readUTF();
                System.out.println("Connected With : "+clientname);
                ClientHandler client = new ClientHandler(s,clientname);
                Thread t = new Thread(client);
                AllClients.add(client);
                t.start();
                System.out.println("Ready to accept connections...");
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }


}

客户端处理程序.java


package server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.Scanner;

public class ClientHandler extends Thread{

    private DataInputStream in;
    private DataOutputStream out;
    private String ClientName;
    private boolean login;
    private Socket Socket;
    Scanner sc = new Scanner(System.in);


    ClientHandler(Socket s,String name) throws Exception{
        this.in = new DataInputStream(s.getInputStream());
        this.out = new DataOutputStream(s.getOutputStream());
        this.login = true;
        this.ClientName = name;
        this.Socket = s;
    }
    public void run() {

        while(true) {
            try {
                String received = in.readUTF();
                if(received.equalsIgnoreCase("logout")) {
                    this.login = false;
                    this.out.writeUTF("logout");
                    int i;
                    for(i = 0; i < Server.AllClients.size(); i++) {
                        if(this.ClientName.equals(Server.AllClients.get(i).ClientName))
                            break;
                    }
                    Server.AllClients.remove(i);
                    System.out.println(this.ClientName+" logged out");
                    this.Socket.close();
                    break;
                }
                if(received.equalsIgnoreCase("getlist")) {
                    for(int i = 0; i < Server.AllClients.size(); i++) {
                        out.writeUTF(i+1 +", "+Server.AllClients.get(i).ClientName);
                    }
                    continue;
                }
                if(received.contains(",")) {
                    String[] Message = received.split(",");
                    for(ClientHandler c : Server.AllClients) {
                        if(c.ClientName.equalsIgnoreCase(Message[1]) && c.login) {
                            c.out.writeUTF(this.ClientName +" : "+ Message[0]);
                            c.out.flush();
                            break;
                        }
                    }
                }

            }catch(Exception e) {
                System.out.println("Error :"+e.getMessage());
            }
        }
        try {
            this.in.close();
            this.out.close();
        }catch(Exception e) {
            System.out.println(e.getMessage());
        }
    }
}


客户端.java


package client;

import java.io.*;
import java.net.*;
import java.util.Scanner;

public class Client {
    static DataInputStream dis;
    static DataOutputStream dos;
    static Socket s;
    public static void main(String args[])throws Exception {
            Scanner sc = new Scanner(System.in);
            System.out.println("Enter Cient Name : ");
            String name = sc.nextLine();
            s = new Socket("localhost",1111);
            dis = new DataInputStream(s.getInputStream());
            dos = new DataOutputStream(s.getOutputStream());
            dos.writeUTF(name);
                Thread sendMessage = new Thread(new Runnable()  
                { 
                    @Override
                    public void run() { 
                        while (true) { 

                            String msg = sc.nextLine(); 

                            try {
                                dos.writeUTF(msg);
                                if(msg.equalsIgnoreCase("logout")) {
                                    System.out.println("Logged out");
                                    break;
                                }
                            } catch (IOException e) { 
                                System.out.println("Error in send method :"+e.toString());
                            } 
                        } 
                    } 
                }); 


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

                        while (true) { 
                            try {
                                String msg = dis.readUTF();
                                if(msg.equalsIgnoreCase("logout")) {
                                    System.out.println("Logged out");
                                    break;
                                }
                                System.out.println(msg);

                            } catch (IOException e) { 

                                System.out.println("Error in read method :"+e.getMessage());
                            } 
                        } 
                    } 
                }); 

                sendMessage.start(); 
                readMessage.start(); 


    }


}



如果我的代码有任何不相关的陈述,请建议一种更好的方法来优化代码

标签: javasocketstcpclient-serverserversocket

解决方案


第一个答案是:是的,这是可能的。

第二个答案:这与线程无关,您必须首先考虑(这很重要,但不是首先)。

第三个答案:据我了解,主要数据结构是客户端及其处理程序的集合。在我看来,中间还缺少一个抽象层。首先考虑像“chatRoom”这样的数据结构。连接到服务器的客户端必须向服务器发送一个“chatRoom”名称。然后服务器创建聊天室或将客户端添加到聊天室的客户端集。从那时起,客户可以将他的消息发送到聊天室,而不是直接发送给客户。在进一步的步骤中:为了能够向单个客户端发送消息,您可以例如为每对客户端强制一个聊天室(注意:这可能非常广泛),因此客户端之间的单独通信仍然是可能的。


推荐阅读