I\'m working on a program that plays a guessing game with a server and a client
ID: 3779918 • Letter: I
Question
I'm working on a program that plays a guessing game with a server and a client class. When I run my tests individually they all pass but when run sequentially they fail after the first one. I believe this is caused by the .accept(); but I'm not sure how to fix it. Here is my code.
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class GuessingServer {
public static void main(String[] args)
{
try{
ServerSocket server;
server = new ServerSocket( 5150 );
System.out.println("awaiting client...");
System.out.println("client connected");
Socket client = server.accept();
Scanner in = new Scanner ( client.getInputStream() );
PrintWriter out = new PrintWriter( client.getOutputStream(), true );
String first = in.next();
int high = in.nextInt();
int low = Integer.parseInt(first);
boolean serverRun = true;
while(serverRun == true)
{
if(!first.equals("SHUT DOWN"))
{
System.out.println(low);
System.out.println(high);
int bNum = ((high - low) / 2) + low;
out.println(bNum);
System.out.println(bNum);
String temp = in.next();
if(temp.equals("high"))
{
high = bNum;
System.out.println(temp + ": ");
System.out.println(high);
}
else if(temp.equals("low"))
{
low = bNum;
System.out.println(temp + ": ");
System.out.println(low);
}
else if(temp.equals("won"))
{
System.out.println(temp);
serverRun = false;
}
else if(temp.equals("lost"))
{
System.out.println(temp);
serverRun = false;
}
}
else
{
serverRun = false;
}
}
client.close();
in.close();
out.close();
server.close();
}
catch(IOException e)
{
}
}
}
and here are my test cases:
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.Socket;
import java.util.NoSuchElementException;
import java.util.Random;
import java.util.Scanner;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class GuessingServerTest {
@Test
public void testReflection() {
Class<?> iClass = GuessingServer.class;
Field[] iFields = iClass.getDeclaredFields();
for (Field f : iFields) {
if (!f.isSynthetic()) {
assertTrue ( "Field ""+f.getName()+"" should be private", Modifier.isPrivate( f.getModifiers() ));
assertFalse( "Field ""+f.getName()+"" can't be static", Modifier.isStatic ( f.getModifiers() ));
}
}
}
@BeforeClass
public static void startServer() {
// run server
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
GuessingServer.main( new String[]{ } );
}
});
thread.start();
}
@Before
public void waitTwoSecondsBetweenTests() {
try {
Thread.sleep( 2000 );
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
@Test(timeout=3000)
public void testA_WinningAfter1Try() {
try {
// run client
Socket socket = new Socket( "localhost", 5150 );
Scanner scanner = new Scanner ( socket.getInputStream() );
PrintWriter writer = new PrintWriter( socket.getOutputStream(), true );
writer.println( "101 401" );
// try 1
int actual = scanner.nextInt();
assertEquals( "Incorrect result", 251, actual );
writer.println( "won" );
socket .close();
scanner.close();
}
catch (IOException e) {
e.printStackTrace();
fail( "Error opening client socket" );
}
catch (NoSuchElementException e) {
e.printStackTrace();
fail( "The server didn't return a value" );
}
}
@Test(timeout=3000)
public void testB_WinningAfter2Tries() {
try {
// run client
Socket socket = new Socket( "localhost", 5150 );
Scanner scanner = new Scanner ( socket.getInputStream() );
PrintWriter writer = new PrintWriter( socket.getOutputStream(), true );
writer.println( "37 337" );
// try 1
int actual = scanner.nextInt();
assertEquals( "Incorrect result", 187, actual );
writer.println( "low" );
// try 2
actual = scanner.nextInt();
assertEquals( "Incorrect result", 262, actual );
writer.println( "high" );
// try 3
actual = scanner.nextInt();
assertEquals( "Incorrect result", 224, actual );
writer.println( "high" );
// try 4
actual = scanner.nextInt();
assertEquals( "Incorrect result", 205, actual );
writer.println( "low" );
// try 5
actual = scanner.nextInt();
assertEquals( "Incorrect result", 214, actual );
writer.println( "high" );
// try 6
actual = scanner.nextInt();
assertEquals( "Incorrect result", 209, actual );
writer.println( "high" );
// try 7
actual = scanner.nextInt();
assertEquals( "Incorrect result", 207, actual );
writer.println( "high" );
// try 8
actual = scanner.nextInt();
assertEquals( "Incorrect result", 206, actual );
writer.println( "won" );
socket .close();
scanner.close();
}
catch (IOException e) {
e.printStackTrace();
fail( "Error opening client socket" );
}
catch (NoSuchElementException e) {
e.printStackTrace();
fail( "The server didn't return a value" );
}
}
@Test(timeout=3000)
public void testC_PlayingARandomGame() throws IOException {
final int UPPER = 200;
final int RANGE = 300;
final int TRIES = 9;
final Random random = new Random();
try {
// run client
Socket socket = new Socket( "localhost", 5150 );
Scanner scanner = new Scanner ( socket.getInputStream() );
PrintWriter writer = new PrintWriter( socket.getOutputStream(), true );
int low = random.nextInt( UPPER );
int hi = low + RANGE;
int number = low + random.nextInt( RANGE );
writer.println( low + " " + hi );
int tries = 0;
boolean gameOver = false;
while (!gameOver) {
int guess = scanner.nextInt();
if (guess == number) {
writer.println( "won" );
gameOver = true;
}
else {
if (++tries > TRIES) {
writer.println( "lost" );
gameOver = true;
}
else {
if (guess < number) {
writer.println( "low" );
}
else {
writer.println( "high" );
}
}
}
}
socket .close();
scanner.close();
}
catch (IOException e) {
e.printStackTrace();
fail( "Error opening client socket" );
}
catch (NoSuchElementException e) {
e.printStackTrace();
fail( "The server didn't return a value" );
}
}
@Test(expected = IOException.class)
public void testD_RunsLast_ServerShutsDown() throws IOException {
try {
// running client #1...shuts down server
Socket socket = new Socket( "localhost", 5150 );
PrintWriter writer = new PrintWriter( socket.getOutputStream(), true );
writer.println( "SHUT DOWN" );
socket.close();
}
catch (IOException e) {
e.printStackTrace();
fail( "Error opening client socket" );
}
waitTwoSecondsBetweenTests();
// running client #2...should throw exception (server should have stopped)
new Socket( "localhost", 5150 ).close();
fail( "Socket should not connect after server was shut down" );
}
}
Explanation / Answer
Client Class
import java.io.*;
import java.net.*;
public class GClient {
public static void main(String[] args) throws IOException {
Socket kkSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
kkSocket = new Socket("127.0.0.1", 4444);
out = new PrintWriter(kkSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: taranis.");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: taranis.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye."))
break;
fromUser = stdIn.readLine();
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}
out.close();
in.close();
stdIn.close();
kkSocket.close();
}
}
Server Class
import java.net.*;
import java.io.*;
public class GServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
boolean listening = true;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(-1);
}
System.err.println("Started KK server listening on port 4040");
while (listening)
new GThread(serverSocket.accept()).start();
serverSocket.close();
}
}
Protocol Class
import java.util.*;
public class GProtocol {
int guess = 0, number = new Random().nextInt(100) + 1;
int score = 10;
int guessmade = 0;
boolean gameRunning = true;
Scanner scan = new Scanner(System.in);
public String processInput(String theInput) {
String theOutput = null;
String ID;
System.out.println("Please Enter your ID...");
ID = scan.next( );
System.out.println("Please guess the number between 1 and 100. You have 10 guesses. Your score is however many guesses you have left");
while (guess != number)
{
try {
if ((guess = Integer.parseInt(scan.nextLine())) != number) {
System.out.println(guess < number ? "Higher..." : "Lower...");
score = score - 1; // here the score variable has one value taken away form it each time the user misses a guess
guessmade = +1; // here the guess made variable is given +1 variable
}
else {
System.out.println("Correct!");
}
}
catch (NumberFormatException e) {
System.out.println("Please enter valid numbers! '");
}
}
theOutput = ID + " your score is " + score ; // here the score is returned
return theOutput;}}
Thread class
import java.net.*;
import java.io.*;
public class GThread extends Thread {
private Socket socket = null;
public GThread(Socket socket) {
super("GMultiServerThread");
this.socket = socket;
}
public void run() {
try {
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
String inputLine, outputLine;
GProtocol kkp = new GProtocol();
outputLine = kkp.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = kkp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye"))
break;
}
out.close();
in.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}