I need help adding two-game implementations and a menu selection option to a Java Server-Client Homework. I
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)
- Simple number guesser where all clients can attempt to guess the randomly generated number
- Hint: may want separate commands to start, stop, and guess (or starting lasts for x rounds then stops)
- No need to implement complexities like strikes
- 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
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
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
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 thisExcellence in Business Communication
ISBN: 978-0136103769
9th edition
Authors: John V. Thill, Courtland L. Bovee