Java Server Guessing Game - Multiple Client Issue - java

This is an Issue I am having with my guessing game. Essentially what I want to do is have a server and have many clients connect to it. Currently that is done I am able to connect clients to the server to play a game, a number guessing game. The problem is I want each individual client to be able to play the game. Currently the game is being played on the server itself. So although multiple clients can join, the game starts again each time a client joins. When the correct answer is inputed the server gives the client his score. Just to be clear I am running the server class then I am running the client class. I want to be able to play the game on the client class window not the server window. Here is my code can you please advise me on what to do. The guessing game is derived from the java sun knock knock tutorial. Found here http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html
Thanks.
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();
}
}
}

In Protocol class, you write Messages to System.out. The instance of the Protocol class is executed in the environment of the server, thus the output is printed to the server's output. To show the output in the client's console, you'll have to send the messages via the socket to the client and print it there.

First and foremost, the preferred thing to do is to implement Runnable instead of extend Thread. That doesn't necessarily fix your problem tho.
Now, the thing that's confusing is what you're actually trying to achieve. You said you want multiple clients to play the game, but right now each client that connects to the server starts a new game. I would assume that's the right way to do it, but you seem to want to have a single game instance and multiple clients simultaneously playing on it. That's very counter-intuitive, however you can achieve it if you simply create a single instance of the GProtocol class, pass it to multiple clients and use the synchronize keyword to ensure thread safe access to its data.

Related

Java - Getting error "Socket is closed" when my Client class connects on my Server class

I made two classes in Java named Server.java and Client.java. The Server is listening to a port and is waiting for a Client to connect (using sockets). When the client connects he can type a pair of numbers separated by "space" and if that pair exists in my edge_list.txt file the Server returns "1" to the client, if not it returns "0". After I completed my initial project I wanted to also use Threads so that it can handle multiple users at once, but when the Client connects I get -> java.net.SocketException: Socket is closed.
I reviewed my code and try using flush() instead of close(). Also, I thought I was closing the socket before the user can read the file, but it didn't seem that was the case. Below I will have the Server.java code block and not the Client.java, cause it doesn't seem to be the problem.
Server.java
import java.io.*;
import java.net.*;
import java.util.*;
public class Server {
private static final int PORT = 9999;
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
System.out.println("Server is listening on port " + PORT);
while (true) {
try (Socket socket = serverSocket.accept()) {
System.out.println("Client connected: " + socket);
new ClientHandler(socket).start();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static class ClientHandler extends Thread {
private Socket socket;
ClientHandler(Socket socket){
this.socket = socket;
}
#Override
public void run() {
try {
//Creating Sockets and Streams
InputStream input = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
OutputStream output = socket.getOutputStream();
PrintWriter writer = new PrintWriter(new OutputStreamWriter(output));
while (socket.isConnected() && !socket.isClosed()) {
//Reading what the Client types
String request = reader.readLine();
//Split the values with "space" and store them in an array,
//then parse those values to two integers
String[] values = request.split(" ");
int A = Integer.parseInt(values[0]);
int B = Integer.parseInt(values[1]);
//Check if the pair in the file exists using checkPairInFile() method
boolean exists = checkPairInFile(A, B);
//if it does print 1 else 0
writer.println(exists ? "1" : "0");
//Flush the output to send the response back to the client
writer.flush();
}
//Print the disconnected user
System.out.println("Client disconnected: " + socket);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static boolean checkPairInFile(int A, int B) {
try (Scanner scanner = new Scanner(new File("edge_list.txt"))) {
//Scanning the file lines
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
//Split the values with "space"
String[] values = line.split(" ");
//Parse the values from String -> Int
int a = Integer.parseInt(values[0]);
int b = Integer.parseInt(values[1]);
//if both exist return true
if (A == a && B == b) {
return true;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return false;
}
}
P.S. Thanks in advance for your help, in case this is problem with my Client.java file I will update the post.
This part:
try (Socket socket = serverSocket.accept()) {
System.out.println("Client connected: " + socket);
new ClientHandler(socket).start();
}
accepts a socket, then prints a message, then starts a new thread, then closes the socket. At some point later the new thread finishes starting up and tries to use the socket and realizes it was already closed.
try (...) {...} (officially called try-with-resources) always closes the things when it gets to the }. That's the point of it. If you don't want to close the socket at the } then you shouldn't use this type of statement.

How to retrieve data from a file very fast in Java

I have a situation like, I am provided with a log file that consists of Strings. What I have to do is , I need to retrieve each string from the file and pass through a Socket and when the End of the File reaches it has to go again to the beginning of the file and send again the Strings. I have written a simple code using an infinite thread that sends the strings and when the EOF comes I am closing the file and again re-opening the file using new BufferedReader object. And I am also giving a small amount of 5ms of thread sleep, but after some time my Process is entering into Pause state (Like a Dead Lock). Is there anyway to improve the speed of transfer? or else can I eliminate the Pause state.
Below is my Simple code:
public class Write extends Thread{
private static final String FileName = "Messages.txt";
private static final int port = 8080;
private final int time = 5;
ServerSocket serverSocket;
Socket writeSocket;
#Override
public void run()
{
try
{
serverSocket = new ServerSocket(port);
System.out.println("Server listening on port " + port+ " ...");
Socket writeSocket = serverSocket.accept();
System.out.println("Connected to Client : "+ writeSocket.getLocalSocketAddress());
OutputStream outStream = writeSocket.getOutputStream();
PrintWriter out = new PrintWriter(outStream, true);
BufferedReader input = new BufferedReader(new FileReader(FileName));
String str = "";
while(true)
{
str = input.readLine();
if(str==null ){
input.close();
input = new BufferedReader(new FileReader(FileName));
}
else{
System.out.println("Outgoing Message>>"+str);
out.println(str);
Thread.sleep(time);
}
}
}
catch(IOException e) {System.out.println(e); } catch (InterruptedException ex) {
Logger.getLogger(Write.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Let me give you a simple explanation. Consider the above code is in a Server code. And when I run a client machine in the same PC, I can able to send the messages at some(high) speed but after sometime, both the client and the Server are entering into a Pause state. I feel this like a Dead Lock. The client is showing like the Server is disconnected and again Connected. When I close the Client then again Server is starting. Can anyone tell me is there a way to process the strings at a very high speed?
Re the program blocking, I would suggest:
put a System.out.print("A") before out.println() and a System.out.print("B") after. If it blocks with "A" as the last message in the output, then the problem is at the client side (they're not consuming the data, causing eventually the sender to block).
If the previous situation happens, write your own simple client which just reads data from the socket and throws it away, so you can demonstrate the problem is at the other side.
Re speed, you want to remove the sleep and System.out.println.
Why not use java nio to read all lines?
https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#readAllLines-java.nio.file.Path-java.nio.charset.Charset-
Or is the file too big to do this?
your code that reads the log file is just fine. no need to make it faster. see below (I commented the parts of the code that deal with the socket and the code works well at reading the log file multiple times. there is no sign of slowing down or deadlocks) :
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Write extends Thread {
private static final String FileName = "/tmp/Messages.txt";
private static final int port = 8080;
private final int time = 5;
ServerSocket serverSocket;
Socket writeSocket;
public static void main(String[] args) {
Write write = new Write();
Thread thread = new Thread(new Write());
thread.start();
}
#Override
public void run() {
try {
// serverSocket = new ServerSocket(port);
// System.out.println("Server listening on port " + port + " ...");
// Socket writeSocket = serverSocket.accept();
// System.out.println("Connected to Client : " + writeSocket.getLocalSocketAddress());
//
// OutputStream outStream = writeSocket.getOutputStream();
// PrintWriter out = new PrintWriter(outStream, true);
BufferedReader input = new BufferedReader(new FileReader(FileName));
String str = "";
while (true) {
str = input.readLine();
if (str == null) {
input.close();
input = new BufferedReader(new FileReader(FileName));
} else {
System.out.println("Outgoing Message>>" + str);
//out.println(str);
Thread.sleep(time);
}
}
} catch (IOException e) {
System.out.println(e);
} catch (InterruptedException ex) {
Logger.getLogger(Write.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

Read/write in simple client-server app in Java

I'm new with Java and I'm trying to learn threads and socket. So decide to make simple client-server application following official java tutorial. My idea is simple - server wait for connection, if appears, it makes new thread with new socket, input and output. Client side -> make connection; new thread with socket, input, output and stdIn (to read line and after that send it to the server). But something is wrong (don't have any idea why) with my code. The connection is established, there's no exceptions. Could someone explain why doesn't work and how to fix it? Also could you have any suggestions about the code (probably it's not with best practices and things like that):
Client side:
public class Client {
private BufferedReader reader;
private Socket sock;
private PrintWriter writer;
public static void main(String[] args) {
Client client = new Client();
client.go();
}
public void go() {
setUpNetworking();
}
private void setUpNetworking() {
try{
sock = new Socket("127.0.0.1", 5000);
System.out.println("Network established");
ServerThread serverThread= new ServerThread(sock);
serverThread.start();
System.out.println("Type your message: ");
} catch (IOException e) {
System.out.println("Problem with establishing the network: " + e);
}
}
class ServerThread extends Thread {
Socket socket;
PrintWriter out;
BufferedReader in;
BufferedReader stdIn;
ServerThread(Socket socket) {
this.socket = socket;
try{
out = new PrintWriter(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
stdIn = new BufferedReader(new InputStreamReader(System.in));
}catch (IOException e) {
System.out.println("Problem with trying to read/write to server: " + e);
}
}
#Override
public void run() {
String fromServer;
String fromClient;
while(true){
try{
if((fromServer = in.readLine()) != null) System.out.println(" " + fromServer);
else if((fromClient = stdIn.readLine()) != null) out.println(fromClient);
}catch(Exception e) {
System.out.println("msg exception: " + e);
}
}
}
}
}
Server side:
public class Server {
//Run server until keepGoing = false
private boolean keepGoing = true;
public static void main(String[] args) {
Server server = new Server();
server.go();
}
public void go() {
try {
ServerSocket serverSocket = new ServerSocket(5000);
while(keepGoing) {
Socket clientSocket = serverSocket.accept();
ClientThread t = new ClientThread(clientSocket);
t.start();
}
} catch (IOException e) {
System.out.println("Problem with socket/network: " + e);
}
}
class ClientThread extends Thread {
Socket clientSocket;
PrintWriter out;
BufferedReader in;
ClientThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try{
out = new PrintWriter(clientSocket.getOutputStream());
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (IOException e) {
System.out.println("Problem with creating in/out: " + e);
}
}
#Override
public void run() {
String message;
while(keepGoing) {
try{
message = in.readLine();
out.println(message);
System.out.println(message);
} catch (IOException e){
System.out.println("Exception while try to read line: " + e);
}
}
}
}
}
PS I've changed a bit the code - instead of made ClientThread Class, I made new runnable class and pass that variable to thread class. Inspired by this question: "implements Runnable" vs. "extends Thread".
I think the problem is that both server and client are waiting for any input. Server:
message = in.readLine();
Client:
if((fromServer = in.readLine()) != null)
System.out.println(" " + fromServer);
else if((fromClient = stdIn.readLine()) != null)
out.println(fromClient);
But the client code already blocks on the fromServer = in.readLine() part, so it never gets to read from standard in, and thus nothing will be sent out to the server.
You could move your attempt to read from standard in to the setUpNetworking method, right after the System.out.println("Type your message: ");. Build a loop there which you exit if the user types "exit" or "quit" or something like that:
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String read = "";
do {
read = stdIn.readLine();
System.out.println("Read from stdin: " + read);
serverThread.send(read);
}
while (!read.equals("exit"));
The ServerThread.send() method is simple:
void send(String string) {
System.out.println("Sending to server: " + string);
out.println(string);
}
However, to make it work, you either have to flush the stream manually after writing to out, or use the following constructor:
out = new PrintWriter(socket.getOutputStream(), true);
See the PrintWriter's JavaDoc: True means auto-flush on newline.
I tested this setup and it worked for me. I was able to send something from the client to the server.
However, this is only the first step. I would implement both reading and writing as separate threads, for both client and server. And there is no graceful shutdown of sockets implemenented yet. A more complete yet simple example can be found on Oracle.

Server not receiving in socket communication

I'm trying to make a Java program in which the server generates a random number and, after establishing a connection with a client, lets it guess the number. However, they both don't seem able to receive each others' messages.
Server side:
package numberguessserv;
import java.net.*;
import java.io.*;
import java.util.Random;
import java.util.Scanner;
public class NumberGuessServ {
public static void main(String[] args) {
Scanner inpkb = new Scanner(System.in);
Random randomGenerator = new Random();
int randomNum = randomGenerator.nextInt(10);
String number = Integer.toString(randomNum);
int port;
boolean isGuessed = false;
String msgReceived;
Socket connect = new Socket();
System.out.print("port: ");
port = inpkb.nextInt();
try {
ServerSocket clSock = new ServerSocket(port);
System.out.println("Waiting...");
connect = clSock.accept();
System.out.println("Connection established with"+connect.getInetAddress());
InputStreamReader isr = new InputStreamReader(connect.getInputStream());
BufferedReader isrBuff = new BufferedReader(isr);
OutputStreamWriter osw = new OutputStreamWriter(connect.getOutputStream());
BufferedWriter oswBuff = new BufferedWriter(osw);
while (!isGuessed) {
msgReceived = isrBuff.readLine();
System.out.println("Number received: "+msgReceived);
if (msgReceived.equals(number)) {
isGuessed = true;
oswBuff.write("Right!");
oswBuff.flush();
}
else {
oswBuff.write("Wrong!");
oswBuff.flush();
}
if (isGuessed)
System.out.println("Number was guessed right.");
else
System.out.println("Number was guessed wrong.");
}
}
catch (Exception ex) {
System.out.println("An exception has occurred: "+ex);
}
finally {
try {
connect.close();
}
catch (Exception ex) {
System.out.println("An exception has occurred: "+ex);
}
}
}
}
Client side:
package numberguessclient;
import java.io.*;
import java.util.Scanner;
import java.net.*;
public class NumberGuessClient {
public static void main(String[] args) {
Scanner inpkb = new Scanner(System.in);
int port;
String IP;
boolean isGuessed = false;
String number, msg;
Socket serv = new Socket();
System.out.print("IP: ");
IP = inpkb.next();
System.out.print("port: ");
port = inpkb.nextInt();
try {
serv = new Socket(IP,port);
System.out.println("Connetion established with"+serv.getInetAddress());
InputStreamReader isr = new InputStreamReader(serv.getInputStream());
BufferedReader isrBuff = new BufferedReader(isr);
OutputStreamWriter osw = new OutputStreamWriter(serv.getOutputStream());
BufferedWriter oswBuff = new BufferedWriter(osw);
while (!isGuessed) {
System.out.print("number: ");
number = inpkb.next();
oswBuff.write(number);
oswBuff.flush();
System.out.println("Number sent.");
msg = isrBuff.readLine();
System.out.println("The reply was received: "+msg);
if (msg.equals("Right!")) {
isGuessed = true;
System.out.println(msg);
}
else {
System.out.println(msg+"\nTry again...");
}
}
}
catch (Exception ex) {
System.out.print("An exception has occurred: "+ex);
}
finally {
try {
serv.close();
}
catch (Exception ex) {
System.out.print("An exception has occurred: "+ex);
}
}
}
}
The readLine() waits for the end of line. Unless and until it gets a new line character, it will wait up there reading.
So, you need to give a new line characer '\n' every time you give an input to the output stream so that the readLine() reads a new line character and does not wait.
Currently in your code, you need to give a new line character everytime you are giving input by doing the following:
oswBuff.write("any message");
oswBuff.write('\n'); //add this statement everywhere you are writing to the output stream
oswBuff.flush();
This complies well for both the server as well as client.
That's expected. Both ends read using
isrBuff.readLine();
So, they both expect the other end to send a line. But none of them sends a line. They both do
oswBuff.write(number);
oswBuff.flush();
That sends some characters, but doesn send any newline character. The receiving end doesn't have any way to know that the end of line has been reached, and it thus continues blocking until it receives the EOL.

java.lang.NullPointerException and java.net.SocketException

I’m trying to socket program in Java. Here the client sends a string which should be reversed by the server and sent back to the client. The server is a multithreaded server. Here is the client-side code:
import java.io.*;
import java.net.*;
class ClientSystem
{
public static void main(String[] args)
{
String hostname = "127.0.0.1";
int port = 1234;
Socket clientsocket = null;
DataOutputStream output =null;
BufferedReader input = null;
try
{
clientsocket = new Socket(hostname,port);
output = new DataOutputStream(clientsocket.getOutputStream());
input = new BufferedReader(new InputStreamReader(clientsocket.getInputStream()));
}
catch(Exception e)
{
System.out.println("Error occured"+e);
}
try
{
while(true)
{
System.out.println("Enter input string ('exit' to terminate connection): ");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String inputstring = br.readLine();
output.writeBytes(inputstring+"\n");
//int n = Integer.parseInt(inputstring);
if(inputstring.equals("exit"))
break;
String response = input.readLine();
System.out.println("Reversed string is: "+response);
output.close();
input.close();
clientsocket.close();
}
}
catch(Exception e)
{
System.out.println("Error occured."+e);
}
}
}
Here is the server side code:
import java.io.*;
import java.net.*;
public class ServerSystem
{
ServerSocket server = null;
Socket clientsocket = null;
int numOfConnections = 0, port;
public ServerSystem(int port)
{
this.port = port;
}
public static void main(String[] args)
{
int port = 1234;
ServerSystem ss = new ServerSystem(port);
ss.startServer();
}
public void startServer()
{
try
{
server = new ServerSocket(port);
}
catch(Exception e)
{
System.out.println("Error occured."+e);
}
System.out.println("Server has started. Ready to accept connections.");
while(true)
{
try
{
clientsocket = server.accept();
numOfConnections++;
ServerConnection sc = new ServerConnection(clientsocket, numOfConnections, this);
new Thread(sc).start();
}
catch(Exception e)
{
System.out.println("Error occured."+e);
}
}
}
public void stopServer()
{
System.out.println("Terminating connection");
System.exit(0);
}
}
class ServerConnection extends Thread
{
BufferedReader br;
PrintStream ps;
Socket clientsocket;
int id;
ServerSystem ss;
public ServerConnection(Socket clientsocket, int numOfConnections, ServerSystem ss)
{
this.clientsocket = clientsocket;
id = numOfConnections;
this.ss = ss;
System.out.println("Connection "+id+" established with "+clientsocket);
try
{
br = new BufferedReader(new InputStreamReader(clientsocket.getInputStream()));
ps = new PrintStream(clientsocket.getOutputStream());
}
catch(Exception e)
{
System.out.println("Error occured."+e);
}
}
public void run()
{
String line, reversedstring = "";
try
{
boolean stopserver = false;
while(true)
{
line = br.readLine();
System.out.println("Received string: "+line+" from connection "+id);
//long n = Long.parseLong(line.trim());
if(line.equals("exit"))
{
stopserver = true;
break;
}
else
{
int len = line.length();
for (int i=len-1; i>=0; i--)
reversedstring = reversedstring + line.charAt(i);
ps.println(""+reversedstring);
}
}
System.out.println("Connection "+id+" is closed.");
br.close();
ps.close();
clientsocket.close();
if(stopserver)
ss.stopServer();
}
catch(Exception e)
{
System.out.println("Error occured."+e);
}
}
}
I get a java.lang.NullPointerException on the server side code when I enter the string and when i try to re-enter the string I get a java.net.SocketException: Socket closed exception.
Client side output:
Enter input string ('exit' to terminate connection):
usa
Reversed string is: asu
Enter input string ('exit' to terminate connection):
usa
Error occured.java.net.SocketException: Socket closed
Server side output:
Server has started. Ready to accept connections.
Connection 1 established with Socket[addr=/127.0.0.1,port=3272,localport=1234]
Received string: usa from connection 1
Received string: null from connection 1
Error occured.java.lang.NullPointerException
I tried a lot but I don't get from where I get these exceptions.
These 3 lines are the culprits in the client code:
output.close();
input.close();
clientsocket.close();
Put them outside of the while loop, and in the finally block:
try {
while(true) {
// client code here
}
} catch (Exception e) {
e.printStackTrace(); // notice this line. Will save you a lot of time!
} finally {
output.close(); //close resources here!
input.close();
clientsocket.close();
}
The issue is that as it was originally, you closed every resource, but in the next iteration, you wanted to use them agai, without initialising them...
Sidenote
Properly handling exceptions including proper logging of them. Always use either a logging framework like log4j
LOG.error("Unexpected error when deionizing the flux capacitor",e);
, or the printStackTrace() method
e.printStackTrace();
And don't forget to include the line numbers in your code, if you post a stacktrace....
EDIT
For the reversed issue:
else
{
int len = line.length();
reversedString=""; //this line erases the previous content of the reversed string
for (int i=len-1; i>=0; i--) { //always use brackets!!!
reversedstring = reversedstring + line.charAt(i);
}
ps.println(""+reversedstring);
}
What happened? The reversedString just grew and grew with each iteration, without getting erased... This is why I like to declare my variables in just the most strict scope I need them.
EDIT
To make the exit command no tkill the server, this can be one (very simple) solution:
In the ServerConnection class:
while(true)
{
line = br.readLine();
System.out.println("Received string: "+line+" from connection "+id);
if(line.equals("exit"))
{
break; //just stop this connection, don't kill server
}
else if(line.equals("stop"))
{
stopserver = true; //stop server too
break;
}
else
{
int len = line.length();
for (int i=len-1; i>=0; i--) {
reversedstring = reversedstring + line.charAt(i);
}
ps.println(""+reversedstring);
}
}
What is happening here? There is a new "command" stop, which makes the server stop, and the exit just exits the client, but does not stop the server itself...
in the 1st run of the loop you are closing all the connections which is causing the issue.
output.close();
input.close();
clientsocket.close();,move it down
Your server is calling br.readLine(); It will wait until the client sends it, but once you send a String you call:
output.close();
input.close();
clientsocket.close();
That will release the resource and result in br.readLine() being null
if (line.equals("exit")) { Here line is null, therefore you cannot call equals.
if ("exit".equals(line)) { You can change it like this to prevent that exception here.
Move the close statements to a finally block, even in the server should, if you have an exception in the while, the close are never reached, that may cause memory leaks.
Client:
} finally {
output.close();
input.close();
clientsocket.close();
}
Server:
} finally {
br.close();
ps.close();
clientsocket.close();
}
Note: you can validate them before closing to ensure they are not null.
You may have to provide a case for the input being null anyway, either exit the loop, usually you would use something like this:
if (null==line || "exit".equals(line)) {
If the client sends a null, something is wrong.

Categories

Resources