1

I am having a login screen and now say we have 2 users with username:amit and ajay and their password: "pass" and "word".Now i want that suppose their are two desktop applications open on same system.I want that multiple clients access the server concurrently.

Meaning say in one login screen amit enters the username and then his thread should sleep and in second login screen let ajay enter his username then amit will again enter his password after that ajay enter his password.How to do it in java?Please help .

user3462609
  • 105
  • 2
  • 11

2 Answers2

6

Here I am sharing you a nice Client Server Authentication Application having one server that is communicating with multiple clients using TCP protocol as per your requirement.

Answer:

Here each client is connected in a separate thread from server and that thread contains all the information about the client. It will solve your concurrency problem.


See inline comments for more clarification.

Note: replace host name in LiveChatClient.java file before running this program at port no 1234

Steps to run the program:

  • First run LiveChatServer only for single time
  • Then run LiveChatClient for multiple clients as many as you want to add

Here is one more sample in the same context. Please have a look at Java Server with Multiclient communication.


Opcode.java:

Operation code that is used to set a client-server communication protocol

/**************** an interface to define different operation code **************/

public interface Opcode {
    int CLIENT_USERNAME = 1;
    int CLIENT_INVALID_USERNAME = 2;
    int CLIENT_PASSWORD = 3;
    int CLIENT_INVALID_PASSWORD = 4;
    int CLIENT_CONNECTED = 5;
}

LiveChatServer.java:

Single server that is controlling multiple clients

/************************ Live Chat Server *******************/

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.LinkedHashMap;

public class LiveChatServer {

    // Connection state info
    private static LinkedHashMap<String, ClientThread> clientInfo = new LinkedHashMap<String, ClientThread>();

    // TCP Components
    private ServerSocket serverSocket;

    // Main Constructor
    public LiveChatServer() {

        startServer();// start the server
    }

    public void startServer() {
        String port = "1234";

        try {
            // in constractor we are passing port no, back log and bind address whick will be local
            // host
            // port no - the specified port, or 0 to use any free port.
            // backlog - the maximum length of the queue. use default if it is equal or less than 0
            // bindAddr - the local InetAddress the server will bind to

            int portNo = Integer.valueOf(port);
            serverSocket = new ServerSocket(portNo, 0, InetAddress.getLocalHost());
            System.out.println(serverSocket);

            System.out.println(serverSocket.getInetAddress().getHostName() + ":"
                    + serverSocket.getLocalPort());

            while (true) {
                Socket socket = serverSocket.accept();
                new ClientThread(socket);
            }
        } catch (IOException e) {
            System.out.println("IO Exception:" + e);
            System.exit(1);
        } catch (NumberFormatException e) {
            System.out.println("Number Format Exception:" + e);
            System.exit(1);
        }
    }

    public static HashMap<String, ClientThread> getClientInfo() {
        return clientInfo;
    }

    // *********************************** Main Method ********************

    public static void main(String args[]) {
        new LiveChatServer();
    }

}

LiveChatClient.java:

Multiple clients connected to single server

/************************ Live Chat Client *******************/

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;

public class LiveChatClient {
    private String chatName;
    private String password;
    private String serverAddress;

    // TCP Components
    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;

    public LiveChatClient() {

        initHostName();
        runClient();// have fun
    }

    public void initHostName() {
        try {
            serverAddress = "<your system name>";
            if (serverAddress == null)
                System.exit(1);

            serverAddress = serverAddress.trim();
            if (serverAddress.length() == 0)// empty field
            {
                System.out.println("Server IP Address or Name can't be blank.");
                initHostName();
                return;
            }
            System.out.println("Trying to connect with server...\nServer IP Address:"
                    + serverAddress);

            // create socket
            InetAddress inetAddress = InetAddress.getByName(serverAddress);
            if (!inetAddress.isReachable(60000))// 60 sec
            {
                System.out
                        .println("Error! Unable to connect with server.\nServer IP Address may be wrong.");
                System.exit(1);
            }

            initPortNo();
        } catch (SocketException e) {
            System.out.println("Socket Exception:\n" + e);
            initHostName();
            return;
        } catch (IOException e) {
            initHostName();
            return;
        }
    }

    public void initPortNo() {
        try {

            String portNo = "1234";

            portNo = portNo.trim();
            if (portNo.length() == 0)// empty field
            {
                System.out.println("Server port No can't be blank.");
                initPortNo();
                return;
            }
            System.out.println("Trying to connect with server...\nServer Port No:" + portNo);

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

        } catch (IOException e) {
            System.out.println("IO Exception:\n" + e);
            initPortNo();
            return;
        }
    }

    public void sendChatName() throws IOException {
        System.out.println("Enter user name:");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String name = br.readLine();
        if (name == null)
            System.exit(1);

        // title case (get only first 9 chars of chat name)
        chatName = name.trim();

        if (name.length() == 0) {
            System.out.println("Please enter user name.");
            sendChatName();
            return;
        }

        // sending opcode first then sending chatName to the server
        out.println(Opcode.CLIENT_USERNAME);
        out.println(chatName);
    }

    public void sendPassword() throws IOException {
        System.out.println("Enter password:");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String name = br.readLine();
        if (name == null)
            System.exit(1);

        // title case (get only first 9 chars of password)
        password = name.trim();

        if (name.length() == 0) {
            System.out.println("Please enter password.");
            sendPassword();
            return;
        }

        // sending opcode first then sending password to the server
        out.println(Opcode.CLIENT_PASSWORD);
        out.println(password);
    }

    public void runClient() {
        try {
            sendChatName();
            while (true) {
                int opcode = Integer.parseInt(in.readLine());
                switch (opcode) {
                    case Opcode.CLIENT_INVALID_USERNAME:
                        // this client is connecting
                        System.out.println(chatName + " is invalid user name. Try different one.");
                        sendChatName();

                        break;

                    case Opcode.CLIENT_PASSWORD:
                        sendPassword();

                        break;

                    case Opcode.CLIENT_INVALID_PASSWORD:
                        // this client is connecting
                        System.out.println(password + " is invalid password. Try different one.");
                        sendPassword();

                        break;

                    case Opcode.CLIENT_CONNECTED:
                        System.out.println(chatName + " is connected successfully.");

                        break;

                }
            }
        } catch (IOException e) {
            System.out.println("Client is closed...");
        }
    }

    // *********************************** Main Method ********************

    public static void main(String args[]) {
        new LiveChatClient();
    }

}

ClientThread.java:

Multiple thread started by server one for each client and containing information about all connected clients

/************************ Client Thread *******************/

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

public class ClientThread implements Runnable {
    // TCP Components
    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;
    private String chatName;
    private String password;

    // seperate thread
    private Thread thread;

    // boolean variable to check that client is running or not
    private volatile boolean isRunning = true;

    // opcode
    private int opcode;
    private static Map<String, String> userpass = new HashMap<String, String>();

    static {
        userpass.put("amit", "pass");
        userpass.put("ajay", "word");
    }

    public ClientThread(Socket socket) {
        try {
            this.socket = socket;

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

            thread = new Thread(this);
            thread.start();

        } catch (IOException e) {
            System.out.println(e);
        }
    }

    public void run() {
        try {
            while (isRunning) {
                if (!in.ready())
                    continue;

                opcode = Integer.parseInt(in.readLine());// getting opcode first from client
                switch (opcode) {
                    case Opcode.CLIENT_USERNAME:
                        chatName = in.readLine();

                        System.out.println(chatName + " is reqesting to connect.");
                        boolean result1 = userpass.containsKey(chatName);
                        if (result1) {
                            System.out.println(chatName + " is a valid username.");
                            out.println(Opcode.CLIENT_PASSWORD);
                        } else {
                            System.out.println(chatName + " is a invalid username.");
                            out.println(Opcode.CLIENT_INVALID_USERNAME);
                        }

                        break;

                    case Opcode.CLIENT_PASSWORD:
                        password = in.readLine();

                        System.out.println(chatName + " is reqesting to connect having password "
                                + password);
                        boolean result2 = userpass.get(chatName).equals(password);
                        if (result2) {
                            System.out.println(password + " is a valid password for username "
                                    + chatName);
                            out.println(Opcode.CLIENT_CONNECTED);
                        } else {
                            System.out.println(password + " is a invalid password for username "
                                    + chatName);
                            out.println(Opcode.CLIENT_INVALID_PASSWORD);
                        }

                        break;
                }
            }

            // close all connections
            out.close();
            in.close();
            socket.close();
        } catch (IOException e) {
            System.out.println(e);
        }
    }
}

Here is the output when two client are added.

Server:

ServerSocket[addr=computerName/14.98.241.102,port=0,localport=1234]
computerName:1234
abc is reqesting to connect.
abc is a invalid username.
ajay is reqesting to connect.
ajay is a valid username.
ajay is reqesting to connect having password word
word is a valid password for username ajay
amit is reqesting to connect.
amit is a valid username.
amit is reqesting to connect having password word
word is a invalid password for username amit
amit is reqesting to connect having password pass
pass is a valid password for username amit

Client1:(ajay)

Trying to connect with server...
Server IP Address:computerName
Trying to connect with server...
Server Port No:1234
Enter user name:
abc
abc is invalid user name. Try different one.
Enter user name:
ajay
Enter password:
word
ajay is connected successfully.

Client2:(amit)

Trying to connect with server...
Server IP Address:computerName
Trying to connect with server...
Server Port No:1234
Enter user name:
amit
Enter password:
word
word is invalid password. Try different one.
Enter password:
pass
amit is connected successfully.

Use this program as initial starter for your application. Please let me know if you want to add new functionality in the program.

Community
  • 1
  • 1
Braj
  • 46,415
  • 5
  • 60
  • 76
  • Firstly what you meant by replace host name in LiveChatClient.java file before running this program at port no 1234? – user3462609 Mar 30 '14 at 03:03
  • What if i had to show that first user has slept or leaved the resource when second user enters username where to print this message? – user3462609 Mar 30 '14 at 04:20
  • correct this line in my code `serverAddress = "";`. Have you tried it? – Braj Mar 30 '14 at 04:35
  • What message are you talking about? Please explain it more. I really want to help you. – Braj Mar 30 '14 at 04:38
  • Where you want to print this message? – Braj Mar 30 '14 at 04:46
  • On server side obviously that other client has taken over the resource now .and present client has released it – user3462609 Mar 30 '14 at 05:19
  • like say following scenerio happen.Client 1 enters username and then Client 2 enters after him then it hsould be shown that client 1 has sleept for some time or has given up his resources and yes i corrected that server address.It works fine – user3462609 Mar 30 '14 at 05:23
  • Why you want this? multiple clients can connect with server at a time with different sockets. If you want only one client to be connected with server at a time. Then I have to modify my code. – Braj Mar 30 '14 at 05:24
  • I want one client to be connected with server at a time if their are multiple clients then server should interleave betwen the clients requests depending on paeticular time interval say of 5seconds – user3462609 Mar 30 '14 at 05:47
  • Put this additional information in `ClientThread` class. and check for all the connected client threads at interval of 5 seconds. You can mention a `Map` containing all the `ClientThread` based on username and later on you can use it. You can store the time also when it is connected to server. – Braj Mar 30 '14 at 05:51
  • Something like that `private HashMap clientInfo = new HashMap();` and put the values in it at `case Opcode.CLIENT_USERNAME:` if username is valid. Should I share you the code for this change or you got it? – Braj Mar 30 '14 at 05:54
  • You edited the code part according to above situation?Did you get what i wanna say ?Frankly to say i didnt get it.I am so thankful that you are helping so much. – user3462609 Mar 30 '14 at 05:55
  • Its confusing but still Let me try. Right now I am busy. I'll come back after sometime. Meanwhile you can play with my code. Try to understand it. Its very simple. – Braj Mar 30 '14 at 05:57
  • I understand your code now pretty well.But now just wanted to make it function such that one client to be connected with server at a time – user3462609 Mar 30 '14 at 10:57
0

May be you should consider study JavaEE, you are saying is basically is the work that make the servers. Where each client is connect to server to do a login. Now if you need do it 100% desktop in javaSE, you need threads, where each thread will connect to the local login.

JavaEE: http://www.roseindia.net/quickguide/tomcat/Logout.shtml

Threads: http://www.vogella.com/tutorials/JavaConcurrency/article.html

I hope that it helps!!

hcarrasko
  • 2,320
  • 6
  • 33
  • 45
  • Could you please provide sample code for it?Where it could be shown that when each thread is running which is slept? – user3462609 Mar 29 '14 at 15:56