Results 1 to 16 of 16
- 08-30-2008, 09:04 PM #1
Member
- Join Date
- Aug 2008
- Location
- UK
- Posts
- 6
- Rep Power
- 0
[SOLVED] Cant compare strings sent by client
I am writing a small chat client to try to learn networking with Java (and Java in general). I have written a server which works absolutely fine when connected to with Telnet on linux. However, when messages are sent from the client I have written, the server cannot interpret the commands and outputs them as normal messages.
My apologies for the large amount of code I'm posting!
Server.java:
ClientHandler.javaJava Code:import java.io.*; import java.net.*; class Server { public static final int PORT = 9988; public static final int MAX_CLIENTS = 3; public int connectedClients = 0; private ClientHandler[] clients = new ClientHandler[MAX_CLIENTS]; public Server() { try { ServerSocket socket = new ServerSocket(PORT); System.out.println("Server started."); while (true) { if (connectedClients<MAX_CLIENTS) { Short a=0; while (clients[a]!=null) { a++; } clients[a] = new ClientHandler(socket.accept(),a,this); connectedClients++; System.out.println("Client connected. Current clients: "+connectedClients); clients[a].start(); } else { Socket extraClient = socket.accept(); DataOutputStream output = new DataOutputStream(extraClient.getOutputStream()); output.writeChars("Sorry, server is full. Try again later.\n"); extraClient.close(); } } } catch(IOException error) { System.out.println("Oops! Error while starting server"); } } public static void main(String args[]) { Server server = new Server(); while (true); } public void clientClosing(Short index) { String leaver = clients[index].name; clients[index] = null; connectedClients--; System.out.println("Client disconnected. Current clients: "+connectedClients); sayAll("*** "+leaver+" has left."); } public void sayAll(String message) { for(Short a=0;a<MAX_CLIENTS;a++) { if (clients[a]!=null) { clients[a].say(message+"\n"); } } System.out.println("Message sent to all: "+message); } public void sayOne(String name, String message, short from) { boolean foundClient=false; for (short a=0;a<MAX_CLIENTS;a++) { if (clients[a]!=null) { if (clients[a].name.equalsIgnoreCase(name)) { clients[a].say(message+"\n"); System.out.println("Message sent to "+clients[a]+": "+message); foundClient = true; break; } } } if (!foundClient) { clients[from].say("Message not sent: "+message+"\nName not found: "+name+".\n"); } } public boolean getNameTaken(String checking, short clientIndex) { boolean toReturn = false; for (short a = 0; a<MAX_CLIENTS; a++) { if (a!=clientIndex&&clients[a] != null) { if (clients[a].name!=null) { if (clients[a].name.equals(checking)) { toReturn = true; break; } } } } return toReturn; } }
Client.java:Java Code:import java.io.*; import java.net.*; class ClientHandler extends java.lang.Thread { Socket client; Short index; Server host; DataOutputStream output; BufferedReader input; String name = null; boolean running = true; short helpLength = 6; String[] help = new String[] {"*** Help for the messaging thing.\n***\n", "*** To quit, type '/#quit'\n", "*** To change your name, type '/#name <new_name>'.\n", "*** To send a private message, type '/#pm <recipient> <message>'.\n", "*** Otherwise, simply type your message and press enter!\n***\n***\n***\n", "*** You just lost the game!\n\n"}; short welcomeLength = 2; String[] welcome = new String[] {"*** Boo! You have connected. How amaxing!\n", "*** Please identify yourself.\n"}; public ClientHandler(Socket handlee, Short arrayIndex, Server host) { client = handlee; index = arrayIndex; this.host = host; try { output = new DataOutputStream(client.getOutputStream()); } catch (IOException error) { System.out.println("Failed to get output stream for client "+index); } try { input = new BufferedReader(new InputStreamReader(client.getInputStream())); } catch (IOException error) { System.out.println("Failed to get input stream for client "+index); } } public void run() { if (running) { try { for (int a=0;a<welcomeLength;a++) { output.writeChars(welcome[a]); } } catch(IOException error) { System.out.println("Oops! Error sending welcome message."); } giveName(); host.sayAll("*** "+name+" has joined."); System.out.println("Client "+index+" is called "+name); while (running) { String receivedMessage=null; try { receivedMessage = input.readLine(); } catch (IOException error) { System.out.println("Error while receiving message."); } try { if (receivedMessage!=null) { if (receivedMessage.trim().equalsIgnoreCase("/#quit")) { output.writeChars("*** You are leaving the chat.\n"); quit(); } else if (receivedMessage.trim().equalsIgnoreCase("/#help")) { for (int a=0;a<helpLength;a++) { output.writeChars(help[a]); } } else if (receivedMessage.toLowerCase().startsWith("/#pm")) { String[] splitMessage = receivedMessage.split(" ",3); if (splitMessage.length==3) { host.sayOne(splitMessage[1],"<from "+name+"> "+splitMessage[2],index); } else { output.writeChars("*** Please follow the correct format of '/#pm <recipient> <message>'.\n"); } } else if (receivedMessage.toLowerCase().startsWith("/#name")) { System.out.println("receivedMessage="+receivedMessage); receivedMessage+=" "; System.out.println("now receivedMessage="+receivedMessage); String[] splitMessage = receivedMessage.split(" ",2); System.out.println("splitMessage[0]="+splitMessage[0]); System.out.println("splitMessage[1]="+splitMessage[1]); resetName(splitMessage[1]); } else { if (receivedMessage.equalsIgnoreCase("help")||receivedMessage.equalsIgnoreCase("/help")) { output.writeChars("*** For help type '/#help'\n"); } host.sayAll("<"+name+"> "+receivedMessage); } } } catch (IOException error) { System.out.println("Error while reacting after receiving message from client "+index); } } } } public void quit() { try { stopThread(); input.close(); output.close(); client.close(); } catch(IOException error) { System.out.println("Error while closing (input stream, output stream or client socket for) client "+index); } host.clientClosing(index); } public void giveName() { try { while (name == null) { name = input.readLine(); } if (name.equals(name.split(" ")[0])) { if (host.getNameTaken(name,index)) { output.writeChars("*** That name is taken. Please enter another.\n"); name = null; giveName(); } else { output.writeChars("*** Name accepted. To change your name type '/#name <new_name>'.\n"); } } else { output.writeChars("*** That name is invalid. Remember: spaces are not allowed.\n"); giveName(); } } catch (IOException error) { System.out.println("Error while setting name for client "+index); } } public void resetName(String newName) { try { String[] splittedNewName = newName.split(" "); if (newName.trim()!=null && newName.trim()!="" && newName!="") { if (newName.trim().equals(splittedNewName[0])) { newName = newName.trim(); if (host.getNameTaken(name,index)) { output.writeChars("*** That name is taken. Please enter another.\n"); } else { output.writeChars("*** New name accepted.\n"); System.out.println("Client "+index+" ("+name+") is now called "+newName); name = newName; } } else { output.writeChars("*** That name is invalid. Remember: spaces are not allowed.\n"); } } } catch (IOException error) { System.out.println("Error while resetting name for client "+index); } } public void say(String message) { try { output.writeChars(message); } catch (IOException error) { System.out.println("Error while sending message to client "+index); } } public void stopThread() { running = false; } }
ClientSender.java:Java Code:import java.io.*; import java.net.*; class Client { Socket socket; public static String SERVER_NAME; public static int SERVER_PORT; public static String habladora; ClientSender sender; ClientReceiver receiver; public Client(String name, int port, String nick) { SERVER_NAME = name; SERVER_PORT = port; habladora = nick; try { socket = new Socket(SERVER_NAME,SERVER_PORT); } catch(UnknownHostException error) { System.out.println("Could not connect to server "+SERVER_NAME+":"+SERVER_PORT+" (a)"); } catch(IOException error) { System.out.println("Could not connect to server "+SERVER_NAME+":"+SERVER_PORT+" (b)"); } sender = new ClientSender(socket, habladora); receiver = new ClientReceiver(socket); sender.start(); receiver.start(); } public static void main(String[] args) { Client client; if (args.length == 3) { client = new Client(args[0],Integer.valueOf(args[1]),args[2]); } else { client = new Client("localhost",9988,"Chris"); } while(true); } public void closeClient() { try { socket.close(); sender.stopThread(); receiver.stopThread(); } catch(IOException error) { System.out.println("Could not close socket for server."); } } }
ClientReceiver.java:Java Code:import java.net.*; import java.io.*; class ClientSender extends Thread { Socket server; BufferedReader inStream; boolean running = true; DataOutputStream output; String habladora; public ClientSender(Socket server, String name) { this.server = server; habladora = name; try { output = new DataOutputStream(server.getOutputStream()); } catch (IOException error) { System.out.println("Failed to get output stream for server."); } try { output.writeChars(habladora+"\n"); } catch(IOException error) { System.out.println("Error while giving name to server."); } inStream = new BufferedReader ( new InputStreamReader(System.in) ); } public void run() { System.out.println("Sender thread started."); while (running) { String inMessage=""; try { inMessage = inStream.readLine(); if(!inMessage.trim().equals("")) { if (inMessage.equals("/#quit")) { output.writeChars("/#quit\n"); System.out.println("Attempting quit."); } else { output.writeChars(inMessage+"\n"); } } } catch(IOException error) { System.out.println("Error while inputting or sending message"); } } } public void stopThread() { running = false; } }
Can anyone shed light on what the problem might be?Java Code:import java.net.*; import java.io.*; class ClientReceiver extends Thread { Socket server; BufferedReader input; boolean running = true; public ClientReceiver(Socket server) { this.server = server; } public void run() { System.out.println("Receiver thread started."); try { input = new BufferedReader(new InputStreamReader(server.getInputStream())); } catch (IOException error) { System.out.println("Failed to get input stream for server."); } while(running) { String receivedMessage=null; try { receivedMessage = input.readLine(); } catch (IOException error) { System.out.println("Error while receiving message."); } if(receivedMessage!=null) { System.out.println(receivedMessage); } } } public void stopThread() { running = false; } }
Thanks,
Chris.Last edited by christuart; 08-31-2008 at 12:49 PM.
- 08-31-2008, 05:47 AM #2
- Join Date
- Jul 2007
- Location
- Colombo, Sri Lanka
- Posts
- 11,374
- Blog Entries
- 1
- Rep Power
- 18
- 08-31-2008, 12:48 PM #3
Member
- Join Date
- Aug 2008
- Location
- UK
- Posts
- 6
- Rep Power
- 0
By normal message I mean a message that is not a command; "Hi" rather than "/#quit".
The section that interprets the input from the client to see if it is a command or not is in ClientHandler.java
- 08-31-2008, 12:50 PM #4
Cheeses :) What a long code !
Also there is no good problem explanation. Try to use form:
1) What you do
2) What you expect
3) What you get
Would be helpfull if you wrote to log data which is sent/received over network and used this data in the explanation.
- 08-31-2008, 01:08 PM #5
Member
- Join Date
- Aug 2008
- Location
- UK
- Posts
- 6
- Rep Power
- 0
OK.
I type into my client "Hello", and the server sends back (to all users) "<chris> Hello" just as it should.
Next I type in "/#quit". This should cause the server to close my connection and make the client close (I think). However, instead the server doesn't notice that this is the quit command and it sends to all users "<chris> /#quit".
Serverside output.
Clientside output (including text from input).Server started.
Client connected. Current clients: 1
Message sent to all: *** Chris has joined.
Client 0 is called Chris
Message sent to all: <Chris> Hello
Message sent to all: <Chris> /#quit
Hope that makes it more clear.Sender thread started.
Receiver thread started.
*** Boo! You have connected. How amaxing!
*** Please identify yourself.
*** Name accepted. To change your name type '/#name <new_name>'.
*** Chris has joined.
Hello
<Chris> Hello
/#quit
Attempting quit.
<Chris> /#quit
- 08-31-2008, 01:45 PM #6
Senior Member
- Join Date
- Aug 2008
- Posts
- 384
- Rep Power
- 5
When you receive the message, use this:
Just start debugging at the beginning; if the above code doesn't output anything, try outputting the message without an if statement. If it does go one step further. For example, in the if statement, put:Java Code:if (receivedMessage.startsWith("/")) { System.out.println("message: "+receivedMessage); }. etc.Java Code:if (receivedMessage.startsWith("/#quit"))I die a little on the inside...
Every time I get shot.
- 08-31-2008, 02:39 PM #7
Have you tried debugging your client code to see what strings it receives? Add a println() fto show receivedMessage after:
Likewise on the server, display ALL the traffic.receivedMessage = input.readLine();
A suggestion:
Instead of entering command strings separately in each program (you may type them differently any time), define them as constants (static) in one place and use the variable names in your code. Then you can be sure they are all referencing the same value for a String or whatever type the variable is.
- 08-31-2008, 03:32 PM #8
- 08-31-2008, 05:35 PM #9
Member
- Join Date
- Aug 2008
- Location
- UK
- Posts
- 6
- Rep Power
- 0
Unfortunately not :/ The reason for the newline characters is that readLine function reads up to a newline. It isn't included in the string.
I have done some more debugging (I'd already printed out what the server received, and it was just "/#quit" as it should be).
This line, at the start of the checks to see what has been sent, returns true if you type in "/#quit". However,Java Code:if (receivedMessage.trim().toLowerCase().startsWith("/"))doesn't... What!? I also tested it with "\u002F\u0023" just to see if that would make any difference for some strange reason, but it didn't.Java Code:if (receivedMessage.trim().toLowerCase().startsWith("/#"))
- 08-31-2008, 06:29 PM #10
Have you ever displayed the contents of receivedMessage & receivedMessage.trim().toLowerCase() just before the if test
to see what is being received, etc? It could help you figure out what is happening.
- 08-31-2008, 09:12 PM #11
quit does not call stop
Shouldn't this be:Java Code:if (inMessage.equals("/#quit")) { output.writeChars("/#quit\n"); System.out.println("Attempting quit."); }
Also, it should not be needful to do while(true); in a properly threaded codebase. In general such things should be fixed as they may conceal un-expected changes when fixed later.Java Code:if (inMessage.equals("/#quit")) { output.writeChars("El intentar parado, amigos mas fina.\n"); System.out.println("Attempting quit."); stopThread(); }Introduction to Programming Using Java.
Cybercartography: A new theoretical construct proposed by D.R. Fraser Taylor
- 08-31-2008, 10:03 PM #12
Member
- Join Date
- Aug 2008
- Location
- UK
- Posts
- 6
- Rep Power
- 0
Sorry, what do you mean, Nicholas? That wouldn't send the quit command to the server. (Also, I don't want to stop the thread there yet for debugging reasons.)
OK, I have found that the problem is that the message sent over the network has a mysterious character between each of the intended characters. I.E. I send "Hello" and the server receives "?H?e?l?l?o?". I can get rid of it, but does anyone have any idea where it might come from?Last edited by christuart; 08-31-2008 at 10:07 PM. Reason: Didn't refresh to see a new post
- 09-01-2008, 12:19 AM #13
Looks like char vs byte problem.
Is the ? character a binary 0?
Use String.charAt() to get some and display with Integer.toHexString() to see what it is.
Look at what output.writeChars does. It writes 2 bytes to the output stream.
Has the code worked before? T thought your posts showed it worked?
- 09-01-2008, 12:43 AM #14
who's on first....
This question of stopping the server ( ?.... ) is modeled by the classic comedy routine who's on first. Given that you have client[] then it is clientArray[index].stopOperations();
What I discovered was some code seeking /#quit then printing that to console but not doing anything about it,... that is what my short code tries to convey: if ( command == stop ){stop that client;}
Also, sometimes ? is actually compiler notation for no memory for that variable so let's be careful in discovering where the '?' character is actually generated.....
Eranga and I are more interested in a giant switch tool....
{ for debugging write everyting to a file......remove println statements for shipping }Last edited by Nicholas Jordan; 09-01-2008 at 12:58 AM. Reason: debugging
Introduction to Programming Using Java.
Cybercartography: A new theoretical construct proposed by D.R. Fraser Taylor
- 09-01-2008, 01:00 AM #15
Member
- Join Date
- Aug 2008
- Location
- UK
- Posts
- 6
- Rep Power
- 0
It did do something about it: it sends the command to the server, which shuts the socket. It didn't stop the client program at the point I posted, but that was for the purpose of debugging.
The actual digit was not a "?", simply a character that wasn't displaying in the kernel.
I got someone I know to look at it and they said that it was a problem with using DataOutputStream.writeChars() - aparently it was sending 2 bytes each time where it should've been sending 1 - and that replacing the DataOutputStream with a PrintStream and using PrintStream.println() would work, which it does, so problem solved.
Is this what you meant by chars vs byte, Norm? If so you were right :)
Thanks all for your help on the matter and I shall take into account the other suggestions given for the program.
Thanks!
Chris
- 09-01-2008, 03:24 AM #16
Similar Threads
-
Identify Client in Socket Client Server Application
By masadjie in forum NetworkingReplies: 1Last Post: 12-20-2007, 09:18 AM -
jsp program for client side printer to print these 2 strings on 3/3
By for453 in forum JavaServer Pages (JSP) and JSTLReplies: 0Last Post: 08-07-2007, 04:42 PM -
i want how to make aprint client side printer to print these 2 strings on 3/3 inch pa
By for453 in forum NetworkingReplies: 0Last Post: 08-06-2007, 06:54 PM -
how to compare two strings
By elizabeth in forum New To JavaReplies: 7Last Post: 08-06-2007, 03:57 AM -
Compare 2 XML
By Peter in forum XMLReplies: 1Last Post: 07-05-2007, 02:58 AM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks