Question: I need help adding two-game implementations and a menu selection option to a Java Server-Client Homework. I was given an attached code to this question

I need help adding two-game implementations and a menu selection option to a Java Server-Client Homework.

I was given an attached code to this question that needs to be worked on, which is listed below.

*Explanation needed for each step that included altering of document*

I would like to implement Coin Toss and Simple Number Guesser

Instructions Follow: - Must-Have a Menu for the Client to select between games,

Implement two of the following server-side activities for all connected clients (majority of the logic should be processed server-side and broadcasted to all clients if/when applicable)

  1. Simple number guesser where all clients can attempt to guess the randomly generated number
    1. Hint: may want separate commands to start, stop, and guess (or starting lasts for x rounds then stops)
    2. No need to implement complexities like strikes
  2. Coin toss command (random heads or tails)

SERVER SIDE:

package Part3Hw;

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

import java.util.Random;

public class Server {

int port = 3001;

// connected clients

private List clients = new ArrayList();

private void start(int port) {

this.port = port;

// server listening

try (ServerSocket serverSocket = new ServerSocket(port);) {

Socket incoming_client = null;

System.out.println("Server is listening on port " + port);

do {

System.out.println("waiting for next client");

if (incoming_client != null) {

System.out.println("Client connected");

ServerThread sClient = new ServerThread(incoming_client, this);

clients.add(sClient);

sClient.start();

incoming_client = null;

}

} while ((incoming_client = serverSocket.accept()) != null);

} catch (IOException e) {

System.err.println("Error accepting connection");

e.printStackTrace();

} finally {

System.out.println("closing server socket");

}

}

protected synchronized void disconnect(ServerThread client) {

long id = client.getId();

client.disconnect();

broadcast("Disconnected", id);

}

protected synchronized void broadcast(String message, long id) {

if (processCommand(message, id)) {

return;

}

// let's temporarily use the thread id as the client identifier to

// show in all client's chat. This isn't good practice since it's subject to

// change as clients connect/disconnect

message = String.format("User[%d]: %s", id, message);

// end temp identifier

// loop over clients and send out the message

Iterator it = clients.iterator();

while (it.hasNext()) {

ServerThread client = it.next();

boolean wasSuccessful = client.send(message);

if (!wasSuccessful) {

System.out.println(String.format("Removing disconnected client[%s] from list", client.getId()));

it.remove();

broadcast("Disconnected", id);

}

}

}

private boolean processCommand(String message, long clientId) {

System.out.println("Checking command: " + message);

if (message.equalsIgnoreCase("disconnect")) {

Iterator it = clients.iterator();

while (it.hasNext()) {

ServerThread client = it.next();

if (client.getId() == clientId) {

it.remove();

disconnect(client);

break;

}

}

return true;

}

return false;

}

public static void main(String[] args, String message) {

System.out.println("Starting Server");

Server server = new Server();

int port = 3000;

System.out.println("Heads or Tails");

try {

port = Integer.parseInt(args[0]);

} catch (Exception e) {

// can ignore, will either be index out of bounds or type mismatch

// will default to the defined value prior to the try/catch

}

server.start(port);

System.out.println("Server Stopped");

}

}

SERVER SIDE THREAD:

package Part3Hw;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.net.Socket;

/**

* A server-side representation of a single client

*/

public class ServerThread extends Thread {

private Socket client;

private boolean isRunning = false;

private ObjectOutputStream out;//exposed here for send()

private Server server;// ref to our server so we can call methods on it

// more easily

private void info(String message) {

System.out.println(String.format("Thread[%s]: %s", getId(), message));

}

public ServerThread(Socket myClient, Server server) {

info("Thread created");

// get communication channels to single client

this.client = myClient;

this.server = server;

}

public void disconnect() {

info("Thread being disconnected by server");

isRunning = false;

cleanup();

}

public boolean send(String message) {

// added a boolean so we can see if the send was successful

try {

out.writeObject(message);

return true;

} catch (IOException e) {

info("Error sending message to client (most likely disconnected)");

// comment this out to inspect the stack trace

// e.printStackTrace();

cleanup();

return false;

}

}

@Override

public void run() {

info("Thread starting");

try (ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());

ObjectInputStream in = new ObjectInputStream(client.getInputStream());) {

this.out = out;

isRunning = true;

String fromClient;

while (isRunning && // flag to let us easily control the loop

(fromClient = (String) in.readObject()) != null // reads an object from inputStream (null would

// likely mean a disconnect)

) {

info("Received from client: " + fromClient);

server.broadcast(fromClient, this.getId());

} // close while loop

} catch (Exception e) {

// happens when client disconnects

e.printStackTrace();

info("Client disconnected");

} finally {

isRunning = false;

info("Exited thread loop. Cleaning up connection");

cleanup();

}

}

private void cleanup() {

info("Thread cleanup() start");

try {

client.close();

} catch (IOException e) {

info("Client already closed");

}

info("Thread cleanup() complete");

}

}

CLIENT SIDE:

package Part3Hw;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.net.Socket;

import java.net.UnknownHostException;

import java.util.Scanner;

public class Client {

Socket server = null;

ObjectOutputStream out = null;

ObjectInputStream in = null;

final String ipAddressPattern = "connect\\s+(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}:\\d{3,5})";

final String localhostPattern = "connect\\s+(localhost:\\d{3,5})";

boolean isRunning = false;

private Thread inputThread;

private Thread fromServerThread;

public Client() {

System.out.println("");

}

public boolean isConnected() {

if (server == null) {

return false;

}

// https://stackoverflow.com/a/10241044

// Note: these check the client's end of the socket connect; therefore they

// don't really help determine

// if the server had a problem

return server.isConnected() && !server.isClosed() && !server.isInputShutdown() && !server.isOutputShutdown();

}

/**

* Takes an ip address and a port to attempt a socket connection to a server.

*

* @param address

* @param port

* @return true if connection was successful

*/

private boolean connect(String address, int port) {

try {

server = new Socket(address, port);

// channel to send to server

out = new ObjectOutputStream(server.getOutputStream());

// channel to listen to server

in = new ObjectInputStream(server.getInputStream());

System.out.println("Client connected");

listenForServerMessage();

} catch (UnknownHostException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return isConnected();

}

/**

*

* Check if the string contains the connect command

* followed by an ip address and port or localhost and port.

*

*

* Example format: 123.123.123:3000

*

*

* Example format: localhost:3000

*

* https://www.w3schools.com/java/java_regex.asp

*

* @param text

* @return

*/

private boolean isConnection(String text) {

// https://www.w3schools.com/java/java_regex.asp

return text.matches(ipAddressPattern)

|| text.matches(localhostPattern);

}

private boolean isQuit(String text) {

return text.equalsIgnoreCase("quit");

}

/**

* Controller for handling various text commands.

*

* Add more here as needed

*

*

* @param text

* @return true if a text was a command or triggered a command

*/

private boolean processCommand(String text) {

if (isConnection(text)) {

// replaces multiple spaces with single space

// splits on the space after connect (gives us host and port)

// splits on : to get host as index 0 and port as index 1

String[] parts = text.trim().replaceAll(" +", " ").split(" ")[1].split(":");

connect(parts[0].trim(), Integer.parseInt(parts[1].trim()));

return true;

} else if (isQuit(text)) {

isRunning = false;

return true;

}

return false;

}

private void listenForKeyboard() {

inputThread = new Thread() {

@Override

public void run() {

System.out.println("Listening for input");

try (Scanner si = new Scanner(System.in);) {

String line = "";

isRunning = true;

while (isRunning) {

try {

System.out.println("Waiting for input");

line = si.nextLine();

if (!processCommand(line)) {

if (isConnected()) {

out.writeObject(line);

} else {

System.out.println("Not connected to server");

}

}

} catch (Exception e) {

System.out.println("Connection dropped");

break;

}

}

System.out.println("Exited loop");

} catch (Exception e) {

e.printStackTrace();

} finally {

close();

}

}

};

inputThread.start();

}

private void listenForServerMessage() {

fromServerThread = new Thread() {

@Override

public void run() {

try {

String fromServer;

// while we're connected, listen for strings from server

while (!server.isClosed() && !server.isInputShutdown()

&& (fromServer = (String) in.readObject().toString()) != null) {

System.out.println(fromServer);

}

System.out.println("Loop exited");

} catch (Exception e) {

e.printStackTrace();

if (!server.isClosed()) {

System.out.println("Server closed connection");

} else {

System.out.println("Connection closed");

}

} finally {

close();

System.out.println("Stopped listening to server input");

}

}

};

fromServerThread.start();// start the thread

}

public void start() throws IOException {

listenForKeyboard();

}

private void close() {

try {

inputThread.interrupt();

} catch (Exception e) {

System.out.println("Error interrupting input");

e.printStackTrace();

}

try {

fromServerThread.interrupt();

} catch (Exception e) {

System.out.println("Error interrupting listener");

e.printStackTrace();

}

try {

System.out.println("Closing output stream");

out.close();

} catch (NullPointerException ne) {

System.out.println("Server was never opened so this exception is ok");

} catch (Exception e) {

e.printStackTrace();

}

try {

System.out.println("Closing input stream");

in.close();

} catch (NullPointerException ne) {

System.out.println("Server was never opened so this exception is ok");

} catch (Exception e) {

e.printStackTrace();

}

try {

System.out.println("Closing connection");

server.close();

System.out.println("Closed socket");

} catch (IOException e) {

e.printStackTrace();

} catch (NullPointerException ne) {

System.out.println("Server was never opened so this exception is ok");

}

}

public static void main(String[] args) {

Client client = new Client();

try

{

// if start is private, it's valid here since this main is part of the class

client.start();

}catch(

IOException e)

{

e.printStackTrace();

}

}

}

The code requires to be put in a folder named Part3Hw and we used Visual Code for this

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Programming Questions!