Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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");
        }
    }}}
like image 511
human Avatar asked Mar 13 '23 07:03

human


2 Answers

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.

like image 77
Sumit Rathi Avatar answered Mar 16 '23 09:03

Sumit Rathi


Before starting to listen to incoming sockets you should start a new thread. In this thread you can read lines from System.in. (Wrap System.in with InputStreamReader then with BufferedReader). Now when you read a certain command from the console you can print out information regarding the connected clients.

like image 24
Guy Chauliac Avatar answered Mar 16 '23 08:03

Guy Chauliac