Crear una clase de servidor y de cliente de clase para una sala de chat personalizado en Java

Sam:

La explicación del Programa

He creado un servidor de sala de chat utilizando Java que consiste en 3 clases, una clase de servidor, una clase de usuario y una clase sala de chat. También he creado una clase de cliente para interactuar con el servidor. El servidor crea un objeto de usuario cada vez que un cliente se conecta al servidor. Cada objeto de usuario comprueba los salas de chat el usuario está en y se ejecuta un hilo que escuchas para la entrada del usuario. Un objeto de servidor recorre cada sala de chat para ver si se ha utilizado en la última semana.

El problema

Me pregunto cómo realmente hacer una conexión con un servidor con el objeto de cliente. Actualmente puedo abrir dos instancias de eclipse. Tengo mi programa de servidor en uno, y mi programa cliente en el otro, pero recibo nada en la consola de cualquiera, lo que debería suceder porque el servidor debe enviar información al cliente, que el cliente se mostrará en la consola. La persona en el cliente final podría entonces dar entrada que el cliente iba a tomar y enviar al servidor.

Me pregunto por qué no está pasando nada en este momento, y qué mejoras puedo hacer.


principal archivos


Server.java

/*
 * Creates a server that can host up to 10 clients who can join chat rooms, post messages in chatrooms, and view posts made by other clients within the same chat room
 */
public class Server implements Runnable{
    protected ArrayList<User> userList; //A list of users, where each user is a client connected to the server
    protected LinkedList<Chatroom> chatRooms;   //A list of chatrooms where each client can post messages in, where messages can be seen by all clients in the chatroom
    private ServerSocket serverSocket;  //The socket for the server

    /*
     * Constructor for the server class. Initializes the server attributes,
     */
    public Server() {
        this.userList = new ArrayList<User>(10);
        this.chatRooms = new LinkedList<Chatroom>();
        try {
            this.serverSocket = new ServerSocket(5000);
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
     * Creates a new user when a client connects to the server, and starts a user thread
     */
    public void createUser() {
        try {
            Socket userSocket = serverSocket.accept();
            Thread user = new Thread(new User(userSocket, this));
            user.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
     * Creates a chatroom for clients to interact in
     * @param roomName: The name of the chat room to be created
     */
    protected Chatroom createChatRoom(String roomName) {
        Chatroom room = new Chatroom(roomName);
        return room;
    }

    /*
     * Receives messages from clients and performs actions based on the requests of the client
     * (non-Javadoc)
     * @see java.lang.Thread#run()
     */
    public void run() {
        long currentTime;
        while(true) {
            try {
                currentTime = System.currentTimeMillis() / 1000;
                //Loop through each chatroom and check if the chatroom has been used(joined or had a message sent to it) and remove that chatroom if it hasn't been used in a week
                for (int i = 0; i < chatRooms.size(); i++) {
                    if (currentTime - 604800 >= chatRooms.get(i).dateLastUsed) {
                        chatRooms.remove(i);
                        //Also remove the chatroom from clients lists of chatrooms
                    }
                }

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

    public static void main(String args[]) {
        Server server = new Server ();
        server.run();
    }
}

Client.java

public class Client extends Thread{
    private String ip = "127.0.0.1";
    private int port = 5000 ;
    private Socket socket;
    private DataInputStream iStream;
    private DataOutputStream oStream;
    private String input;

    public Client() {
        try {
            this.socket = new Socket(ip, port);
            this.iStream = new DataInputStream(socket.getInputStream());
            this.oStream = new DataOutputStream(socket.getOutputStream());
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * Sends a message to the user
     * @param message: The message to be sent to the user
     */
    protected void send (String message) {
        try {
            oStream.writeUTF(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
     * Closes the connection to the client
     */
    protected void close () {
        try {
            iStream.close();
            oStream.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
     * Runs a thread for the client to constantly receive the clients input(non-Javadoc)
     * @see java.lang.Thread#run()
     */
    public void run() {
        try {
            Scanner reader = new Scanner(System.in);
            input = iStream.readUTF();
            String userInput;//Check if there is input from the user
            while (input != null) {
                input = iStream.readUTF();
                System.out.println(input);
                userInput = reader.next();
                oStream.writeUTF(userInput);
            }
            reader.close();
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String args[]) {
        Client client = new Client();
        client.run();
    }

}

Objetos utilizados por Server.java


User.java

//Each user represents a client that has connected to the server
public class User implements Runnable{
    private DataInputStream inputStream;
    private DataOutputStream outputStream;
    private Socket socket;
    private String name;
    protected LinkedList<Chatroom> chatRooms;
    private String input;
    private Server server;

    /*
     * User Constructor, create a user for each client connecting to the server
     * @socket The socket that the user will be communicated through
     * The client is prompted to create a name for themself, they are they prompted to do an action.
     */
    public User(Socket socket, Server server) {
        this.socket = socket;
        this.server = server;
        try {
            inputStream = new DataInputStream(socket.getInputStream());
            outputStream = new DataOutputStream(socket.getOutputStream());
            outputStream.writeUTF("Enter a name");
            this.name = inputStream.readUTF();
            String message = "Create a chatroom: create \nList Chat Rooms: list \n Join Chat Room: join \n Leave Chat Room: Leave";
            send(message);
        } catch (IOException e) {   
        }
    }

    /*
     * Returns the current amount of chatrooms this user is in
     */
    protected int chatRoomLength () {
        return this.chatRooms.size();
    }

    /*
     * Gets the most recent input from the user
     */
    protected String getInput() {
        return input;
    }

    /*
     * Puts a user/client in a chatroom
     * @param cRoom: The chatroom that the user will join 
     */
    protected void joinRoom (Chatroom cRoom) {
        chatRooms.add(cRoom);
    }

    /*
     * Removes a user/client from a chatroom
     */
    protected void leaveRoom (Chatroom c) {
        chatRooms.removeFirstOccurrence(c);
    }

    /*
     * Sends a message to the user
     * @param message: The message to be sent to the user
     */
    protected void send (String message) {
        try {
            outputStream.writeUTF(message);
        } catch (IOException e) {
        }
    }

    /*
     * Closes the connection to the client
     */
    protected void close () {
        try {
            inputStream.close();
            outputStream.close();
            socket.close();
        } catch (IOException e) {}
    }

    /*
     * Runs a thread for the client to constantly receive the clients input(non-Javadoc)
     * @see java.lang.Thread#run()
     */
    public void run() {
        try {
            input = inputStream.readUTF();  //Check if there is input from the user
            //if the user has disconnected from the server, remove them from the list
            if (input == null) {
                this.close();
                this.server.userList.remove(this);
            }else if (input.equals("create")){  //create a chat room
                this.send("Name the Chatroom");
                input = this.getInput();
                Chatroom c = this.server.createChatRoom(input);
                this.joinRoom(c);
            }else if (input.equals("list")) {   //List the current chatrooms
                String rooms = "";
                for (int j = 0; j< server.chatRooms.size(); j++) {
                    rooms = rooms + server.chatRooms.get(j).getName() + "\n";
                }
                this.send(rooms);
            }else if (input.equals("join")) {   //Join the user to a chat room
                int end = chatRooms.size();
                if (end == 0) {
                    this.send("There's currently no chat rooms");
                }else { 
                    this.send("Which room would you like to join");
                    input = this.getInput();
                    for (int k = 0; k < end; k++) {
                        if (chatRooms.get(k).getName().equals(input)) {
                            Chatroom joinRoom = chatRooms.get(k);
                            this.joinRoom(joinRoom);
                            String message = "Chatroom " + input + " messages. \n";
                            //Print the current messages in the chatroom to the user
                            for (int j = 0; j < joinRoom.messages.size(); j++ ) {
                                message = message + joinRoom.messages.get(j) + "\n";
                            }
                            this.send(message);
                        } else if (k == end - 1) {
                            this.send("There's no chat rooms by that name");
                        }
                    }
                }
            }else if (input.equals("leave")) {  //Remove the user from a chatroom
                int end = this.chatRoomLength();    //if the chatroom list of the user is empty
                if (end == 0) {
                    this.send("You are not in any Chat Rooms");
                }else {
                    this.send("Which room would you like to leave");
                    input = this.getInput();

                    for (int m = 0; m < end; m++) { //find the chatroom by the same name
                        if (this.chatRooms.get(m).getName().equals(input)) {
                            this.chatRooms.remove(m);
                            this.send("Great! You've been removed from" + input);
                        } else if (m == end - 1) {
                            this.send("You're not in a chatroom named" + input);
                        }
                    }
                }
            }else { //All other input is interpreted as a message to be posted in the chatrooms that the user is in
                int end = this.chatRoomLength();
                if (end == 0) {
                    this.send("You can't write to any chat rooms because you are not in any");
                }
                for (int m = 0; m < end; m++) { //Add the users message to ALL the chatrooms the user is in
                    Chatroom c = this.chatRooms.get(m);
                    c.addMessage(input);
                    //Send this added message to all the users in this chatroom
                    for (int n = 0; n < c.users.size(); n++) {
                        User u = c.users.get(n);
                        u.send("Chatroom" + c.getName() + ":" + input);
                    }
                }
            }

        }catch (IOException e) {
        }
    }
}

Chatroom.java

public class Chatroom {
    private String name;        //Name of the chatroom
    protected LinkedList<String> messages;  //List of text messages that have been sent by users to the chatroom and are displayed in the chatroom
    protected long dateLastUsed;        //The last time the chatroom was joined or had a message sent to it
    protected LinkedList<User> users;   //The clients/users that are currently in the chatroom

    /*
     * Chatroom constructor
     * @param name The name of the chatroom, as determined by the user creating it
     */
    public Chatroom(String name) {
        dateLastUsed = System.currentTimeMillis() / 1000;       //Sent the time that the chatroom was used last to the current UNIX Epoch time
        messages = new LinkedList<String>();
        this.name = name;
    }

    /* 
     * Adds a message into the chatroom
     * @param message The message to be added to the chatroom
     */
    protected void addMessage(String message) {
        messages.add(message);
        dateLastUsed = System.currentTimeMillis() / 1000;
    }

    /*
     * Returns the name of the chatroom
     * @return String equal to the name of the chatroom
     */
    protected String getName() {
        return this.name;
    }

}
Jaikanth J:

En primer lugar, no hay una llamada a createUser()la que tiene el código para aceptar la conexión de socket.

El siguiente es el código de run()la función,

try {
            Scanner reader = new Scanner(System.in);
            input = iStream.readUTF();
            String userInput;//Check if there is input from the user
            while (input != null) {
                input = iStream.readUTF();
                System.out.println(input);
                userInput = reader.next();
                oStream.writeUTF(userInput);
}

Una vez que el enchufe se acepta los grabados de servidor Enter a nameque se almacenan de entrada, dentro del bucle, mientras que hay otra readUTF()llamada.

El problema con la readUTF()llamada es que está bloqueando, es decir. si no hay una writeUTF()llamada desde el servidor espera a los datos.

He resuelto el problema por el siguiente fragmento,

try {
            Scanner reader = new Scanner(System.in);
            String userInput;//Check if there is input from the user
            do {
                input = iStream.readUTF();
                System.out.println(input);
                userInput = reader.next();
                oStream.writeUTF(userInput);
            } while (input != null);
            reader.close();
        }

Incluso esta no es la solución óptima, ya que necesitaría servidor de escribir algo en la corriente cada vez.

Otra solución sería la de leer y escribir utilizando diferentes hilos de esa manera que sería capaz de crear un full-duplex como el chat, a diferencia de este medio dúplex.

Luego hubo algunos NPE debido a ninguna inicialización de chatRoomsLinkedList,

Además de algunos errores lógicos gusta, no añadiendo salas de chat a su lista.

Codigo erroneo:

protected Chatroom createChatRoom(String roomName) {
        Chatroom room = new Chatroom(roomName);
        return room;
    }

Corregido Código:

protected Chatroom createChatRoom(String roomName) {
        Chatroom room = new Chatroom(roomName);
        this.chatRooms.add(room);
        return room;
    } 

La mejor manera de resolver todos los errores sería Github y algunos colaboradores: p

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=179419&siteId=1
Recomendado
Clasificación