Search code examples
javamysqlsocketsclient-serverserversocket

How to get input from server console in a client server program


I have implemented a customer interface using java (multithreaded). On the client side customer logs in when the server is already running. Multiple clients can login creating a thread for each client. What I want to achieve is when multiple clients are logged in I want to enter a command in server console(eclipse) that lists all the clients logged in after i input something on console.

ClientSide of the code:

btnLogin.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                Connection conn = null;
                try // try block
                {
                    // declare variables
                    String username = "";
                    String pwd = "";

                    // get values using getText() method
                    username = loginEmail.getText().trim();
                    pwd = new String(loginPassword.getPassword());

                    // check condition it field equals to blank throw error
                    // message
                    if (username.equals("") || pwd.equals("")) {
                        JOptionPane.showMessageDialog(null, " name or password or Role is wrong", "Error",
                                JOptionPane.ERROR_MESSAGE);
                    } else // else insert query is run properly
                    {
                        String IQuery = "select accountnumber, customername, address from `customeraccount` where emailaddress=? and password=?";
                        String accnum = null;
                        System.out.println("Connecting to a selected database...");

                        // STEP 3: Open a connection
                        conn = DriverManager.getConnection(DB_URL, user_name, password);
                        System.out.println("Connected database successfully...");
                        PreparedStatement stmt = conn.prepareStatement(IQuery);
                        stmt.setString(1, username);
                        stmt.setString(2, pwd);
                        ResultSet rs = stmt.executeQuery();
                        while (rs.next()) {
                            detailName.setText(rs.getString("customername"));
                            detailAddress.setText(rs.getString("address"));
                            accnum = rs.getString("accountnumber");
                        }
                        out.println(accnum);
                        out.println(detailName.getText());
                        rs.close();
                        ((java.sql.Connection) conn).close();
                    }
                } catch (SQLException se) {
                    // handle errors for JDBC

                    se.printStackTrace();
                } catch (Exception a) // catch block
                {
                    a.printStackTrace();
                }
            }
        });

Server Side of the code:

public class StoreServer {
static ArrayList<String[]> list2 = new ArrayList<String[]>();

public static void main(String[] args) throws IOException {
    System.out.println("The server is running.");
    int clientNumber = 0;
    ServerSocket listener = new ServerSocket(3355);

    try {
        while (true) {
            new Thread(new Customer(listener.accept(), clientNumber++)).start();
        }
    } finally {
        listener.close();
    }
}

private static class Customer implements Runnable {
    private Socket socket;
    private int clientNumber;

    public Customer(Socket socket, int clientNumber) {
        this.socket = socket;
        this.clientNumber = clientNumber;
        // log("New connection with client# " + clientNumber + " at " +
        // socket);
    }

    /**
     * Services this thread's client by first sending the client a welcome
     * message then repeatedly reading strings and sending back the
     * capitalized version of the string.
     */
    public void run() {
        try {

            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);


            while (true) {

                    System.out.println("Account Number: " + acnum + "  Name: " + name);
                if (acnum == null || acnum.equals(".")) {
                    break;
                }
                // out.println(input.toUpperCase());
            }
        } catch (IOException e) {
            log("Error handling client# " + clientNumber + ": " + e);
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                log("Couldn't close a socket, what's going on?");
            }
            // log("Connection with client# " + clientNumber + " closed");
        }
    }}}

Solution

  • Here is the snippet you want :

    private static class CommandListener implements Runnable {
    
        @Override
        public void run() {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            while(true) {
                try {
                    String command = br.readLine();
                    if(command.equals("listClients")) {
    
                        // Assuming you will have static list of customer. In which you will 
                        // add a customer/client when a new client get connected and remove 
                        // when a client get disconnected 
    
                        System.out.println("Total Connected customer :" + customers.size());
                        System.out.println("Details :");
                        for(Customer cust : customers) {
                            System.out.println(cust.getName());
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    In your StoreServer class create an object of CommandListener class and pass it to a thread just before listening on server port. Something like this:

    public class StoreServer {
    
        static ArrayList<String[]> list2 = new ArrayList<String[]>();
        static List<Customer> customers = new LinkedList<Customer>();
    
        public static void main(String[] args) throws IOException {
            System.out.println("The server is running.");
            int clientNumber = 0;
            ServerSocket listener = new ServerSocket(3355);
            Thread commandListenerThread = new Thread(new CommandListener());
            commandListenerThread.start();
            try {
                while (true) {
                    Socket socket = listener.accept();
                    Customer cust = new Customer(socket, clientNumber++);
                    customers.add(cust);
                    new Thread(cust).start();
                }
            } finally {
                listener.close();
            }
        .....
    

    Please note that this is just a snippet and not a proper and optimized code. Apart from this, there are lot of improvements which could be done in the code you posted, like keeping a threshold on thread creation logic etc. But I am skipping that, as your question is related only to getting input from console in the Server program.