Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Write a Java Program. -The concurrent directory server program runs waiting for

ID: 3864761 • Letter: W

Question

Write a Java Program.

-The concurrent directory server program runs waiting for a connection from a client.

-The clients and the server should (in general) run on different machines.

-Each client can send three different messages to the directory server -- JOIN, LEAVE and LIST. The first two are for joining and leaving the list of peers who are online and are willing to chat. The last is to retrieve the list of online peers. The server responds to these messages with the appropriate actions. Note that the server needs to be concurrent because multiple clients should be able to talk to it simultaneously.

-The LIST message should return all the information (IP address, listening port number of the peer etc) so that a peer can be contacted directly.

-A client should be able to invite the peer for a chat by opening a TCP connection directly.

-You can design the protocol for the chat. A peer should be able to initiate a chat connection, exchange chat messages and either peer should be able to close the connection. The peers need not be concurrent.

-This is meant to be a skeletal program, and you probably will need to impose some limitations; that is fine, just state them clearly.

-You will lose points if your peer programs do not close the sockets when the program quits.

-you should use the socket number 22316

- I have done most of the code, I just need help implementing the chat function. Also My program was having a problem when a client tries to LEAVE, I think I may have the close socket part in the wrong part.

thank you

The Code, GameServer.java


import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.PrintStream;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;


public class GameServer {

    //Port number assigned for connection, 22316 for me
    int portNum;

    //Server socket object to open socket for server class
    private static ServerSocket serverSocket = null;

    //Variable to make server on/Off
    boolean listening;

    // This server can accept up to maxClientsCount clients' connections.
    private static final int maxClientsCount = 10;
    private static final ClientHandler[] threads = new ClientHandler[maxClientsCount];

    //Concurrent Map to hold client address and the respective socket
    private static ConcurrentMap<InetAddress,Socket> clients = null;
  

    // add a concurrent map data structure to store <hostname, socket for that name>,whenever a client is added , it is assigned
    // a thread and a hashmap location
    //thread leaves, thread set to null , socket closes

    //Constructor to initialize Concurrent server class
    public GameServer(int port, int maxThreads) {

        portNum = port;
        listening = true;


        try
        {
            serverSocket = new ServerSocket(portNum);


        } catch (IOException e)
        {
            System.out.println(e.getMessage());
            System.exit(-1);
        }

        clients = new ConcurrentHashMap<InetAddress, Socket>();

        for (int i = 0; i < maxClientsCount; i++)
            threads[i] = null;

    }

    public void runServer() {

        while (listening) {
            try {
                //SOCKET FROM CLIENT
                Socket clientSocket = serverSocket.accept();

                int i = 0;

                for (i = 0; i < maxClientsCount; i++) {
                    if (threads[i] == null) {

                        // New thread, for client
                        ClientHandler newThread = new ClientHandler(clientSocket, clients);

                        //separate thread for new connections
                        threads[i] = newThread;
                        threads[i].setThread(newThread);
                        threads[i].start();
                        break;
                    }
                }
                // If too many clients connected >10
                if (i == maxClientsCount) {
                    PrintStream os = new PrintStream(clientSocket.getOutputStream());
                    os.println("Server too busy. Try later.");
                    os.close();
                    clientSocket.close();
                }

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

        }

    }

}


class ClientHandler extends Thread {

    PrintWriter out = null;
    BufferedReader in = null;

    //CLIENT SOCKET
    private Socket clientSocket = null;

    //Thread pointing to itself
    private ClientHandler thread;


    //Concurrent Hash map of connected clients
    private ConcurrentMap<InetAddress,Socket> connectedClients = null;

    public ClientHandler(Socket _clientSocket, ConcurrentMap<InetAddress,Socket> clients) {
        this.clientSocket = _clientSocket;
        this.connectedClients = clients;
    }
// Make a thread
    public void setThread(ClientHandler _thread){
        this.thread = _thread;
        System.out.println("Thread created for client");
    }

    public void run() {

        try{

        // Input steam, output stream for client
      
            out = new PrintWriter(clientSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

            while(true){

                String input = in.readLine();

                if(input != null) {
                    System.out.println("Received " + input + " from "+clientSocket.getInetAddress().toString().substring(1));


                    if (input.matches("JOIN")) {
//IF JOIN from client
                        connectedClients.put(clientSocket.getInetAddress(), clientSocket);
                        if (connectedClients.containsKey(clientSocket.getInetAddress()))
                            out.println("Client Successfully connected to server");
                        else
                            out.println("Unable to connect client to server due to unknown reasons");

                    } else if (input.matches("LEAVE")) {
//IF LEAVE from client
                        //remove client, null client, close socket
                        if (connectedClients.containsKey(clientSocket.getInetAddress())) {

                            connectedClients.remove(clientSocket.getInetAddress());

                            try {
                                this.out.close();
                                this.in.close();
                                clientSocket.close();
                                this.thread = null;
                            }
                            catch (IOException ex) {
                                System.out.println("Error closing socket");
                            }

                        } else {
                            out.println("You have not joined the list");
                        }

                    } else if (input.matches("LIST")) {
// IF LIST from client
                        if (connectedClients.containsKey(clientSocket.getInetAddress())) {
                            StringBuilder response = new StringBuilder("Clients Connected: ");
                            int num = 1;
                            //append IP address of clients to this string
                            for (InetAddress address : connectedClients.keySet()) {

                                response.append(" "+num+". "+address.toString().substring(1));
                                num++;
                            }

                            out.println(response.toString());

                        } else
                            out.println("You have not joined the list. Cannot display list.");
                    } else {
                        String usage = " Illegal Input. " +
                                " Usage as follows: " +
                                " JOIN : Join the server " +
                                " LIST : List the connected clients " +
                                " LEAVE : Leave the server";
                        out.println(usage);

                    }
                }


            }

        }
        catch(IOException e){

            System.out.println(e.getMessage());
            System.exit(-1);}

        }
        public static void main(String[] args) throws Exception {
           System.out.println("waiting for connections");
    }
}

Explanation / Answer

aio library

An aio library is an OS-provided library that houses a group of APIs for asynchronously inputting or outputting files. In AIX, Asynchronous I/O Subsystem is its aio library; in Linux, libaio is its aio library. The facility for parallel output of system logs uses the API provided by the aio library to issue a request for parallel output of duplexed system log files.

This term has no practical application for Windows users, because it is related to a facility that cannot be used with a Windows edition of HiRDB.

alias IP address

A technique by which different IP addresses can share the same LAN adapter through assignment of multiple IP addresses to the LAN adapter.

all asynchronous method

One of the processing methods used in Real Time SAN Replication. When an update of a database file or system file occurs at the main site, copying to the corresponding file at the remote site is performed asynchronously.

This term has no practical application for Windows users, because it is related to a facility that cannot be used with a Windows edition of HiRDB.

all synchronous method

One of the processing methods used in Real Time SAN Replication. When an update of a database file or system file occurs at the main site, copying to the corresponding file at the remote site is performed synchronously.

This term has no practical application for Windows users, because it is related to a facility that cannot be used with a Windows edition of HiRDB.

alternate BES

A back-end server that takes over processing when an error occurs while the standby-less system switchover (1:1) facility is being used. Similarly, a unit containing an alternate BES is called an alternate BES unit.

asynchronous copy

One of the processing methods used to update-copy data to a remote site. Update-copying at the main site is completed without waiting for update-copying at the remote site to be completed.

This term has no practical application for Windows users, because it is related to a facility that cannot be used with a Windows edition of HiRDB.

asynchronous DB state

In in-memory data processing, synchronous DB state means that data in the in-memory RDAREA is not synchronized with data in the in-memory buffer.

asynchronous group

A group made up entirely of asynchronous pair volumes.

This term has no practical application for Windows users, because it is related to a facility that cannot be used with a Windows edition of HiRDB.

asynchronous pair volume

A pair volume that has been created by specifying async as the fence level. When data is written to the P-VOL, it is not mirrored synchronously onto the S-VOL. Thus, differences might arise between the data on the P-VOL and the data on the S-VOL, even though they are paired.

This term has no practical application for Windows users, because it is related to a facility that cannot be used with a Windows edition of HiRDB.