I am having some problems figuring out this issue. I have a server that takes a string from a client, the first four characters of which act as a ‘command’ of sorts. rep: replaces the stored string, app: appends to it.
This works mostly fine, however when I use the rep: command, it repeats the client’s string twice. So, if I inputted rep:foo the server returns ‘foofoo’. I have tried analysing the code and can’t see any immediate problems.
When adding some test output commands to both the server and the client, to see what the variables hold, I get the result as expected (the string input on the client minus the command characters). The code for both classes is below:
Server:
import java.io.*;
import java.net.*;
import java.util.*;
public class SynchServer
{
public static void main(String[] args) throws IOException
{
ServerSocket serverSocket = null;
final int PORT = 1234;
Socket client;
ClientHandler2 handler; // thread for client
int clientCount = 0;
//set up server socket
try
{
serverSocket = new ServerSocket(PORT);
}
catch(IOException ioEx)
{
System.out.println("Cannot open socket!");
System.exit(1);
}
// client connections and related actions:
do
{
// wait for client...
client = serverSocket.accept();
System.out.println("Client accepted...\n");
// assign client a connection number
clientCount++;
// create thread
handler = new ClientHandler2(client, clientCount);
// run thread
handler.start();
}while(true);
}
}
class ClientHandler2 extends Thread
{
// declare thread variables
private Socket client;
private Scanner input;
private PrintWriter output;
private static String text = "";
int clientNum; // picked up from main
// constructor - set up socket and streams
public ClientHandler2(Socket socket, int clientCount)
throws IOException
{
client = socket;
clientNum = clientCount;
// streams...
// from client
input = new Scanner(client.getInputStream());
// to client
output = new PrintWriter(client.getOutputStream(), true);
}
// thread actions:
public void run()
{
String head, tail, received;
do
{
// read in line from client
received = input.nextLine();
// split input line in two - head is first four
// characters for the command, tail is for rest of
// line - the text to be manipulated:
head = received.substring(0,4);
tail = received.substring(4);
// find command and choose relevant method to execute
if(head.equals("rep:"))
{
replaceText(tail);
}
else if(head.equals("app:"));
{
appendText(tail);
}
// no further tests needed - makes server ignore
// invalid commands (Add some kind of message?)
// send modified (or not) string back to client:
output.println(clientNum + ": " + text);
}while(!received.equals("QUIT"));
// close socket connection
try
{
System.out.println("Closing connection...");
client.close();
}
catch(IOException ioEx)
{
System.out.println("Unable to close connection!");
}
}
private synchronized void replaceText(String value)
{
text = value;
}
private synchronized void appendText(String value)
{
text += value;
}
}
Client:
import java.io.*;
import java.net.*;
import java.util.*;
public class SynchClient
{
public static void main(String[] args) throws IOException
{
// declare variables
InetAddress host = null;
final int PORT = 1234;
Socket socket;
Scanner networkInput, keyboard;
PrintWriter networkOutput;
// assign host address:
try
{
host = InetAddress.getLocalHost();
}
catch(UnknownHostException uhEx)
{
System.out.println("Host ID not found!");
System.exit(1);
}
// Set up socket to server and IO streams:
socket = new Socket(host, PORT);
// from server
networkInput = new Scanner(socket.getInputStream());
// to server
networkOutput =
new PrintWriter(socket.getOutputStream(),true);
// user input
keyboard = new Scanner(System.in);
String message, response;
do
{
// get user input
System.out.print("Enter message ('QUIT' to exit): ");
message = keyboard.nextLine();
// validate user input - ensure string is >= 4 chars
// long
while(message.length() < 4)
{
System.out.print("Try again: ");
message = keyboard.nextLine();
}
// send message to server:
networkOutput.println(message);
// received response from server
response = networkInput.nextLine();
// output server response
System.out.println(response);
}while(!message.equals("QUIT"));
}
}
I really cannot figure this out, and while not vitally important, I’d like to know for reference what is going wrong. So, any hints would be nice.
Dude.
else if(head.equals("app:"));see the semicolon at the end there? 🙂 Remove that, and your problems should magically go away.
edited to add: The semicolon at the end of the
elseblock terminates the condition and the code in the brackets below is thus executed every iteration of the while loop inClientHandler2.run()