Skip to main content
gamedev.net
🔒 Locked

[java] [Solved] Java String Troubles

Started by Stelimar Nov 19, 2008 at 10:14 PM 2 replies 1k views
Original Post
Stelimar
Stelimar
I've been doing some networking stuff in Java lately, and I made a simple chat server where multiple users can register, login and chat with each other. Now I am trying to add the ability to notify users when someone else has logged in, and send the newly logged in user a list of all users currently logged in. The client then keeps a list of all users logged in. The following is the function called when a user logs in:

	public void loggedIn(User user) {
		//Notify all clients that the user logged in
		int userID = user.id;
		SocketChannel userSocket = user.getSocket();
		String[] params = new String[3];
		params[0] = Integer.toString(user.id);
		params[1] = user.name;
		params[2] = STATUS_LOGGED_IN;
		ModuleCommand command = new ModuleCommand(null,this.id,this.id,USER_STATUS,params);
		broadcast(command);
		//Send the user all other users currently logged in
		ListIterator i = users.listIterator();
		params[2] = STATUS_PREVIOUSLY_LOGGED_IN;
		while (i.hasNext()) {
			user = (User) i.next();
			if (user.id != userID) {
				params[0] = Integer.toString(user.id);
				params[1] = user.name;
				command.parameters = params;
				command.socket = userSocket;
				cHandler.sendCommand(command);
			}
		}
	}


The operation of my sockets are based on this tutorial. My problem is that the usernames that are sent are all the same. For example, if user1 logs in, then user2 logs in, then the server will send a "user1 logged in" command both times (I hope that makes sense). However, if I add a simple System.out.println(user.name) somewhere inside of the while loop, then the server sends the correct usernames. I'm thinking this has something to do with the fact that Java stores references to objects in variables rather than the objects themselves, and since the code which actually sends the command to the client is running in a separate thread, the string gets changed before the request is actually processed. However I can't for the life of me figure out an easy way to simply copy a string (and I don't even know for sure if that will fix it). I've tried changing
params[1] = user.name;

to
params[1] = String(user.name);

but I get the error "cannot find symbol : method String(java.lang.String)" which really confuses me, because the Java API reference lists String(String original) as a constructor. Any help would be greatly appreciated. -Stelimar [Edited by - Stelimar on November 19, 2008 11:24:31 PM]
trojanman
trojanman
You will need to create a new object with the original string passed in.
params[1] = new String(user.name);
Codeka
Codeka
It's because you're using the same "params" array for both calls. Presumably your broadcast method does it's actualy work in a seperate thread...

You need to ensure the params is not modified before that thread finishes with it, and the simplest way would be to use a different array for each call:

	public void loggedIn(User user) {		//Notify all clients that the user logged in		int userID = user.id;		SocketChannel userSocket = user.getSocket();		String[] params = new String[3];		params[0] = Integer.toString(user.id);		params[1] = user.name;		params[2] = STATUS_LOGGED_IN;		ModuleCommand command = new ModuleCommand(null,this.id,this.id,USER_STATUS,params);		broadcast(command);		//Send the user all other users currently logged in		ListIterator i = users.listIterator();		while (i.hasNext()) {			user = (User) i.next();			if (user.id != userID) {				String[] params2 = new String[3];				params2[0] = Integer.toString(user.id);				params2[1] = user.name;				params2[2] = STATUS_PREVIOUSLY_LOGGED_IN;				command.parameters = params2;				command.socket = userSocket;				cHandler.sendCommand(command);			}		}	}


By the way, the use of a string array for passing parameters seems rather, un-Javaish. The normal pattern would have a strong-typed sub-class of "ModuleCommand" for each different type of command you can send...
Stelimar
Stelimar
I don't know why I thought of the String being changed but not the Array/ModuleCommand (both of which I needed to create new instances of). Thanks for the help, and the suggestion about handling the parameters. I got it working now =)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.