I'm having problems sending messages from client to server and to server to other clients. Please can you give me a hand by telling me something.
The problem is if I do an input (line 46) I can get an answer from the server (line 51) then continue this loop.
But for example, if the server must notify a user that it's his turn, I wouldn't get the message until I try typing something.
while ((userInput = stdIn.readLine()) != null) {
/* line 46 */ out.println(userInput);
if (userInput.equals("quit")) {
break;
}
/* line 51 */ lines = in.readLine();
System.out.println(lines);
System.out.println("input next command:");
}
You have to make (at least i dont know how else to do it) a separate thread where you get user input, then use message passing (just search "message passing java") for comunication. Server messages will not get blocked by input and you can tryReceive (or some name around that lines) on channel. In main thread query for message from server, then from input channel, sleep a little and repeat. When user presses enter, channel gets filled with his message, main thread takes it when passing by.
Related
I am working on a client/server project for class. I have the server set up so that it is listening for inputs and will relay appropriate message/messages back to the client. For example, client sends input "help" to the server, the server will respond with 5 lines of strings back to the client's console. This is done with the code:
while (true) {
System.out.print('>');
inputLine = bufferedReader.readLine();
toServer.write(inputLine + '\n');
toServer.flush();
while ((serverInput = fromServer.readLine()) != null) {
System.out.println(serverInput);
}
So I believe the problem with this is that it is indefinitely waiting for serverInputs at the end. I would like it to go back to reading inputs from the console after all the appropriate messages have been received. Any help is greatly appreciated. Thank you
I have a made a socket connection between client and server. Everything is working good if i introduce the first comand on client, receiving the message i want from the server.
#server
public PrintWriter out;
out.println(res);
#client
public BufferedReader in = null;
String line;
line = in.readLine();
At the second time i run it won't show the message i send from server cause it will read \n so it will be an empty string. If i change this:
#server
out.println("\n"+res);
The first time i run now it will jump a line, printing just the \n. And the second time i run it will show the right message.
If i change now to:
out.println("\n\n"+res);
It will just show when i introduce something to send to the server and receive back after the 3rd time (the first 2 times it prints \n).
Don't know what to do to show always the message i send from the server. Any advice?
I started to learn about server-client application and I used this Java code example for client and server:
http://docs.oracle.com/javase/tutorial/networking/sockets/examples/EchoServer.java
http://docs.oracle.com/javase/tutorial/networking/sockets/examples/EchoClient.java
I ran both applications on two instances of Eclipse.
The code remain the same, except for the change:
//out.println(inputLine);
System.out.println(inputLine);
In the server side.
And to the printings "Hello", "Bye" in the beginning and end of the main() in the server-side. And of course, I set the IP used by the Client to the IP of my computer (used ipconfig - not unique IP)
From what I understand, everything the client sends should appear on the server standard output until the client types "Cntrl C" (unless I understand wrong).
here is the input I wrote in the client side:
boooooooooo
baaaaaa
paaaaaaa
And this is what I get in the Server-side:
Hello
boooooooooo
Something in here is unexpected to me-
the server seem to run in the main(),
but from some reason after the first printing it stops.
I tried o set breakpoints inside the Client side code on the while-line
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("echo: " + in.readLine());
}
but the program flow encountered the while only twice an then didn't reach there anymore.
when it did enter in, userInput was not evaluated, I suspect because readline() returned null. But why should it? if EOF character wasn't inserted to the standard input in the Client side.
I have noticed that in a few pieces of example code for a TCP chat program, written in Java, both the read string from client and send string to server both occur in main.
For example, here is a tutorial where I don't see the distinction between an input thread and in output thread... http://www.cise.ufl.edu/~amyles/tutorials/tcpchat/TCPChat.java
"BufferedReader input" and "PrintWriter output" are both used with a TCP Socket from within the same thread. As a complete novice, this confuses me because previously, if I had something that waits for input, like the "getch()" get character function from C, that thing that will hold up the thread (unless it is an event or an exception). Normally, when I imagine code in a thread being executed, I imagine it being executed line by line, with occasional jumps in execution for exceptions and events. But writing to a stream and reading from a stream is neither an exception nor an event - I don't know what the main thread would do if it received an input string and was supposed to send out an output string both at the same moment. Is the stream itself actually handled by some other thread or some other program, like the terminal or the OS?
I had felt so weird about this that I split the chat program into two separate threads to make me feel more comfortable - one thread for receiving strings from the TCP socket and another thread for sending strings out through the same socket. Can someone provide an explanation as to why my act of splitting input and output into two separate threads is totally unnecessary? And before someone marks this down due to lack of research and understanding, I did my best to read online Java tutorials on Sockets and I have had experience writing to and reading from streams (terminal and plain text file).
case CONNECTED:
try {
// Send data
if (toSend.length() != 0) {
out.print(toSend); out.flush();
toSend.setLength(0);
changeStatusTS(NULL, true);
}
// Receive data
if (in.ready()) {
s = in.readLine();
if ((s != null) && (s.length() != 0)) {
// Check if it is the end of a trasmission
if (s.equals(END_CHAT_SESSION)) {
changeStatusTS(DISCONNECTING, true);
}
// Otherwise, receive what text
else {
appendToChatBox("INCOMING: " + s + "\n");
changeStatusTS(NULL, true);
}
}
}
}
catch (IOException e) {
cleanUp();
changeStatusTS(DISCONNECTED, false);
}
break;
I took this code snippet from the "main procedure" of the link you provided.
The method that would halt the thread from continuing like you were talking about is in.readLine(); The thread would wait until there was something to read from the input stream before continuing. I would like to point out the if statement " if(in.ready()) " By having that if statement there, the code checks first if the input stream has something to read. Otherwise, it skips over it and continues.
I'm a real newbie to java, so please excuse me if this is a hopelessly straightforward problem.
I have the following from my java game server:
// Get input from the client
DataInputStream in = new DataInputStream (server.getInputStream());
PrintStream out = new PrintStream(server.getOutputStream());
disconnect=false;
while((line = in.readLine().trim()) != null && !line.equals(".") && !line.equals("") && !disconnect) {
System.out.println("Received "+line);
if(line.equals("h")){
out.println("h"+EOF); // Client handshake
System.out.println("Matched 1");
}else if (line.equals("<policy-file-request/>")) {
out.println("..."+EOF); // Policy file
System.out.println(server.getInetAddress()+": Policy Request");
disconnect=true;
System.out.println("Matched 2");
}else if(line.substring(0,3).equals("GET")||line.substring(0,4).equals("POST")){
out.println("HTTP/1.0 200 OK\nServer: VirtuaRoom v0.9\nContent-Type: text/html\n\n..."); // HTML status page
disconnect=true;
System.out.println("Matched 3");
} else {
System.out.println(server.getInetAddress()+": Unknown command, client disconnected.");
disconnect=true;
System.out.println("Matched else");
}
}
server.close();
First of all, the client sends an "h" packet, and expects the same back (handshake). However, I want it to disconnect the client when an unrecognised packet is received. For some reason, it responds fine to the handshake and HTML status request, but the else clause is never executed when there's an unknown packet.
Thanks
From the information added in your comments it seems that what will be happening is the client is sending a single character (e.g. 'n'). The line
line.substring(0,3).equals("GET")||line.substring(0,4).equals("POST"))
will be executed, but since line is only a single character line.substring(0,3) will throw a StringIndexOutOfBoundsException. Either this is causing your program to fail and you haven't mentioned that. Or you have some exception handling going on in another part of your code that you haven't shown and this is either supressing the error or printing a log line or something and again you haven't mentioned this (or noticed it).
Try replacing substring().equals with startsWith
You need to check for null before you trim it. The result of trim() can never be null.
You should check disconnect first, before the readLine(), otherwise you are always doing one readLine() too many.
If you are never getting to your 'else' it means one of the other conditions is always true.
There are a number of problems with your code
in.readLine().trim()
readLine do returns null and calling null.trim() will result in ... NullPointerException
Is there a reason to append EOF to every response you send.
calling substring without making sure it has at least that much elements will throw StringIndexOutOfBoundsException if it is shorter.
Are you testing with "P" for example?
It would seem highly unlikely that the else is not executing. Are you sure your loop does not exit on such packets and hence your conditions do not even run? Does your
System.out.println("Received "+line); print anything for the packet that seems to be missing the else statement?