Warm tip: This article is reproduced from serverfault.com, please click

How can I improve this java chat with multiple clients?

发布于 2020-11-23 20:27:14

for a school project i had to do a chat with multiple users in java. I did it, it works but i don't think is perfect. In the future i want to add a GUI, but before doing that i want to correct it. So my question is how can i improve it? What can i do better?. This is my code. On the Client side i used the main thread to wait the user input and another thread that listen to the server that wait message from another clients. On the server side i used the main thread to accept new connection request from clients and N thread that manage N clients. Please help me.

Client side:
import java.net.*;
import java.io.*;
class listener implements Runnable{
    private Socket connection;
    private static boolean running;
    listener(Socket connection){
        this.connection=connection;
        running=true;
    }
    public void run(){
        InputStreamReader in;
        BufferedReader sIN;
        String msgToRecv;
        try{
            in=new InputStreamReader(connection.getInputStream());
            sIN=new BufferedReader(in);
        }
        catch(IOException e){
            System.out.println(e);
            return;
        }
        while(running){
            try{
                msgToRecv=sIN.readLine();
            }
            catch(IOException e){
                System.out.println("Connection closed: "+e);
                return;
            }
            System.out.println(msgToRecv);
        }
        return;
    }
    public static void stopListening(){
        running=false;
        return;
    }
}
class Client
{
    public static void main(String[] args)
    {
        String ipAddServer="127.0.0.1";
        int port=8080;
        Socket connection=null;
        String msgToSend;
        String username;
        InputStreamReader input=new InputStreamReader(System.in);
        BufferedReader tastiera=new BufferedReader(input);
        OutputStream out;
        PrintWriter sOUT;
        System.out.println("Enter a username");
        try{
            connection=new Socket(ipAddServer, port);
            out=connection.getOutputStream();
            sOUT=new PrintWriter(out);
            username=tastiera.readLine();
        }
        catch(IOException e){
            System.out.println(e);
            return;
        }
        System.out.println("User: "+username);
        System.out.println("Chat Joined");
        Thread t=new Thread(new listener(connection));
        t.start();
        do{
            try{
                msgToSend=tastiera.readLine();
            }
            catch(IOException e){
                System.out.println(e);
                return;
            }
            sOUT.println(username+": "+msgToSend);
            sOUT.flush();
        }while(!msgToSend.equals("EXIT"));
        listener.stopListening();
        try
        {
            connection.close();
        }
        catch(IOException e)
        {
            System.out.println(e);
        }
        return;
    }
}

Server side:

import java.net.*;
import java.io.*;
import java.util.ArrayList;
class clientHandler implements Runnable{
    private ServerSocket sSocket;
    private Socket connection;
    private ArrayList<Socket> sockets;
    public clientHandler(ServerSocket sSocket, Socket connection, ArrayList<Socket> sockets) {
        this.sSocket=sSocket;
        this.connection=connection;
        this.sockets=sockets;
    }
    public void run(){
        InputStreamReader in, input;
        BufferedReader sIN, tastiera;
        OutputStream out;
        PrintWriter sOUT;
        String msgToRecv;
        try{
            out=connection.getOutputStream();
            sOUT=new PrintWriter(out);
            in=new InputStreamReader(connection.getInputStream());
            sIN=new BufferedReader(in);
        }
        catch(Exception e){
            System.out.println(e);
            return;
        }
        sockets.add(connection);
        do{
            try{
                msgToRecv=sIN.readLine();
            }
            catch(IOException e){
                System.out.println(e);
                return;
            }
            for(int i=0;i<sockets.size();++i){
                Socket temp=sockets.get(i);
                if(!connection.equals(temp)&&!msgToRecv.equals("null")){
                    OutputStream tmpOut;
                    PrintWriter tmpSOUT;
                    try{
                        tmpOut=temp.getOutputStream();
                        tmpSOUT=new PrintWriter(tmpOut);
                    }
                    catch(IOException e){
                        System.out.println(e);
                        return;
                    }
                    tmpSOUT.println(msgToRecv);
                    tmpSOUT.flush();
                }
            }
        }while(msgToRecv!=null);
        sockets.remove(sOUT);
        return;
    }
}
class Server
{
    public static void main(String[] args)
    {
        int port=8080;
        ServerSocket sSocket;
        ArrayList<Socket> sockets=new ArrayList<Socket>();
        Thread t;
        try{
            sSocket=new ServerSocket(port);
        }
        catch(IOException e){
            System.out.println(e);
            return;
        }
        while(true){
            try{
                t=new Thread(new clientHandler(sSocket, sSocket.accept(), sockets));
            }
            catch(IOException e){
                System.out.println(e);
                return;
            }
            t.start();
        }
    }
}
Questioner
Andrea Goldoni
Viewed
0
Alireza Akhoundi 2020-11-29 17:51:08

When you develop chat server (better to say soft realtime server) there is some important things :

1. Manage Resources

2. Low Latency

3. Scalability

4. Durability

5. Availability

6. Store Data (chats , files , and ...)

As you are develop this server for school , you can skip section 2 , 3 , 4 and 5 .

Section 1 : Manage Resources in any program is too important , in chat servers too. You have N client and you need N threads? No its not a good idea , there is a good way to handle it with none-blocking-socket that will help you to handle many connections in just one thread. Remember don't create many threads on server and don't waste CPU and Memory. Sometimes you have to know better to reuse allocated buffers instead of creating new one that cause CPU and Memory resources waste.

Section 6 : Store data in a chat server that receive many requests per seconds need be managed. Sometimes need to let data batched and then push them to data store. It will make it too faster than push data one by one , ofcourse databases and their driver library will handle this things in their layer but its too important to batch inside of your application layer. There is many good databases to use in chat server but the best one is Apache Cassandra.

Note : It just not related to develop chat servers but its better to make your code more understandable and programming event-driven (UserConnect , UserDisconnect , MessageRecived and ...). One good practice is to creating your program logic abstract by define Interfaces (for example : AbstractServer , AbstractDataBase and ...) and then make a runnable section for your program that use this Interfaces directly that independent of how this Interfaces works functionally , and then implement this Interfaces. With this model you can make your program divide to smaller parts and make implement program more easier.