Getting stuck on a While Loop using BufferedReader - java

I've been having a problem with using a while loop surrounding a BufferedReader in Java. I'm doing some experiments with Sockets.
My current code:
InetAddress address = InetAddress.getByName(this.IP);
SocketAddress socketaddress = new InetSocketAddress(address, this.port);
Socket socket = new Socket();
socket.connect(socketaddress);
if(socket.isConnected()){
Executor.logger.info("Connection to proxy established!");
}
else {
Executor.logger.warning("Connection to proxy failed!");
socket.close();
return;
}
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String temp2;
while((temp2 = in.readLine()) != null){
Executor.logger.info("Running query says " + temp2);
}
But no matter what I've tried the code will not progress to the next line. It does not spam my logger with anything, it just suddenly stops and gets stuck.
This is client-side only and I am not in control of the receiver server-side.
Am I doing something wrong?
Thanks for any help in advance.
Edits
The server is a command-line that accepts a command with variables and returns with a code that tells you the outcome of what you just did. However, when you first connect it returns something like message, blank line, message, blank line which is the loop currently getting stuck.

After testing I have found an alternative variable that can be used to detect whether the BufferedReader is full or not.
If you change the ((temp2 = in.readLine()) != null) from this code:
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String temp2;
while((temp2 = in.readLine()) != null){
Executor.logger.info("Running query says " + temp2);
}
And use the boolean (in.ready()) instead:
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.write("login " + this.user + " " + this.password);
out.flush();
String temp2;
while(in.ready()){
temp2 = in.readLine();
Executor.logger.info("Running query says " + temp2);
}
It will stop the loop when the BufferedRead has no more data to read and can be re-initialised again whenever necessary by copying the loop again.

Related

While loop doesn't break after reading multiple line of text with BufferedReader in Java Socket

I have trying to send multiple lines of code from a client to the server.
Here is the code on the server side
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
//read client input
//multi line
//https://stackoverflow.com/questions/43416889/java-filereader-only-seems-to-be-reading-the-first-line-of-text-document?newreg=2f77b35c458846dbb1290afce8853930
String line = "";
while((line =in.readLine()) != null) {
System.out.println(line);
}
System.out.println("is it here?");
Here is the code on the client side :
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
while (true) {
System.out.print("> ");
//content server input command (put, lamport clock, message)
String command = keyboard.readLine();
if (command.equals("quit")){
break;
}
//read from CSDB/txt1.txt
String message = readFileReturnString("CSDB/txt1.txt", StandardCharsets.UTF_8);
System.out.println(message);
//send to clientHandler through PrintWriter
out.println(command + " 3 \n" + message);
//receive response from ClientHandler (lamport clock)
String serverResponse = input.readLine();
System.out.println(serverResponse + socket);
}
Server side is able to print out all the text that is sent from the client side. However, the while loop doesn't break and System.out.println("is it here?"); has never been executed.
May I know why and how I can solve this problem please?
Your Client is waiting for some response of the Server. But the Server does not send any response. The Server writes to the System.out only. The Server has to write the response with the out.
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
//read client input
//multi line
//https://stackoverflow.com/questions/43416889/java-filereader-only-seems-to-be-reading-the-first-line-of-text-document?newreg=2f77b35c458846dbb1290afce8853930
String line = "";
while((line =in.readLine()) != null) {
System.out.println(line);
out.println(line); // send Server response
}
System.out.println("is it here?");
# talex
Then you need to tell server when it should exit the loop. Yo may send special string or something.
This works fine.
String line = "";
while((line =in.readLine()) != null) {
System.out.println(line);
if (line.equals("break") {
break;
}
}

Why does server program freeze on line 'String file = br.readLine()'?

I am new to socket programming. I have to write a program where client accepts filename from a user and sends it to the server. The server reads corresponding file and sends its content back to client. Now my problem is server program freezes on 'String file = br.readLine()'. When I terminate my client program, further lines of server code get executed. If I comment out while loop at the end of my client code, server code works perfectly fine(it prints data to standard output). Can you tell what could be wrong with my code?
Server Code:
public class SocketServer {
public static void main(String[] args) throws Exception{
System.out.println("Server is started.");
ServerSocket ss = new ServerSocket(9999);
System.out.println("Server is waiting for a client.");
Socket server = ss.accept();
System.out.println("Client is connected.");
BufferedReader br = new BufferedReader(new InputStreamReader(server.getInputStream()));
String file = br.readLine();
System.out.println("Requested file is: " + file);
OutputStreamWriter os = new OutputStreamWriter(server.getOutputStream());
PrintWriter writer = new PrintWriter(os);
BufferedReader fr = new BufferedReader(new FileReader(file));
String line;
while((line = fr.readLine()) != null) {
writer.write(line);
writer.flush();
System.out.println(line);
}
}
}
Client Code:
public class SocketClient {
public static void main(String[] args) throws Exception {
Scanner in = new Scanner(System.in);
Socket client = new Socket("localhost", 9999);
OutputStreamWriter os = new OutputStreamWriter(client.getOutputStream());
PrintWriter writer = new PrintWriter(os);
System.out.print("Enter filename: ");
String file = in.nextLine();
writer.write(file);
writer.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
System.out.println("Content of " + file + ":");
String str;
while((str = br.readLine()) != null) {
System.out.print(str);
}
System.out.println("File transfer is complete.");
}
}
br.readLine(); will wait for input till it finds a new-line .
writer.write(file); You are writing file name without a new-line.
So in order to make it work either write a newline char at client or read it char by char at server.
Hope this helps.

BufferedReader and BufferedWriter with Socket

geniuses.
I want to used socket in Java.
Here is a part of my server side code:
ServerSocket ss = new ServerSocket(this.portNum);
while (!ss.isClosed()) {
Socket socket = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
System.out.println("reading");
StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
System.out.println("read");
System.out.println("writing");
bw.write(this.wsp.parse(new String(sb.toString())).toJSONString());
bw.newLine();
bw.flush();
System.out.println("wrote");
bw.close();
br.close();
socket.close();
}
ss.close();
And my client side (test) code is:
Socket socket = new Socket("143.248.135.60", 44450);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("writing");
bw.write(str);
bw.newLine();
bw.flush();
System.out.println("wrote");
System.out.println("reading");
StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
System.out.println("read");
br.close();
bw.close();
socket.close();
Both sides halt after printing "reading."
What's wrong with my codes?
Thank you for your help in advance!
Your application blocks at the servers site at this point:
while ((line = br.readLine()) != null) {
sb.append(line);
}
Your servers will read lines until the source stream gets closed (br.readLine() will return null when the end of stream has been reached). But this doesn't happen. It seems that your're expecting just a single line here so try this instead of the loop at the server side:
System.out.println("reading");
String line = br.readLine();
System.out.println("read");
Now about the name loop on the client side: The server will close the streams and the socket immediately after it has written its own data. So br.readLine() will return null on the client side after the first line was read. So it will do what you're expecting. But it will also works if you're replacing the code as I've suggested it for the server side.
Hope it helps.
Edit based on the clarification of the question (need to read multiple lines):
The easiest way based on your work is to use a control character like "End of transmission" (0x04 on ASCII).
Client code:
System.out.println("writing");
bw.write("Hello");
bw.newLine();
bw.write("World");
bw.newLine();
bw.write(0x04); // EOT control character
bw.newLine(); // This is needed for BufferedReader/Writer - even if we've used a EOT
bw.flush();
System.out.println("wrote");
Continued in the next commend...
Server code:
while ((line = br.readLine()) != null && !(line.length() > 0 && line.charAt(0) == 0x04)) {
sb.append(line).append(System.lineSeparator());
}
If you're not using ASCII or UTF8 please review your used encoding to choose the correct control character.

Java sockets - Why do I need a PrintWriter to make this work?

I'm trying to learn socket programming in Java but unfortunately I'm running into some behaviour that I don't understand. I have a very simple client program that connect to a server socket and sends some text that gets echoed back. Said client program looks like this:
try(
Socket socket = new Socket("127.0.0.1", 5001);
OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
){
String userInput = "";
while (!userInput.toLowerCase().equals("quit")) {
userInput = stdIn.readLine();
writer.write(userInput);
writer.flush();
System.out.println("Server response: " + reader.readLine());
}
}
catch(Exception e) {e.printStackTrace();}
When I run this program the first line that I enter gets sent to the server but after that I can enter as many lines as I want and nothing gets sent. I also never see anything printed out by the System.out.println() line.
But if I switch out the OutputStreamWriter for a PrintWriter everything works as it should! Here's the code with PrintWriter:
try(
Socket socket = new Socket("127.0.0.1", 5001);
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
){
String userInput = "";
while (!userInput.toLowerCase().equals("quit")) {
userInput = stdIn.readLine();
writer.println(userInput);
System.out.println("Server response: " + reader.readLine());
}
}
catch(Exception e) {e.printStackTrace();}
Anyone have any idea why the first of the above two programs acts weird while the second one works? If anyone can tell me what the difference between writing with an OutputStreamWriter vs a PrintWriter is then that might tell me what's going on.
Note that the difference between write() and println() is that println() adds a linebreak after the data while write() does not.
So if your server uses readLine() to receive the data with a client using write() it might wait forever for the end of the line to read without receiving it.
So writer.write(userInput + "\n") might do the trick.

Simple Client-Server: flushing not working before or after writing in the buffer

I sending strings to a server but the server get strange chars before the string i've send, I'v tried to flush before send, after send and after inicializating the outputstream variable but the result is the same.I Heard a lot about flush() and also search about it, but still didnt find how to solve my problem, maybe its simple but i cant get it.
please Help me!
Client Side
InetAddress endereco = InetAddress.getByName(null);
socket= new Socket(endereco, SServer.PORTO);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(new ObjectOutputStream(socket.getOutputStream()),true);
while(true){
System.out.println("Write your Thoughs.. ");
Scanner scanner = new Scanner(System.in);
String Msg = scanner.nextLine();
System.out.println("I Said: ");
System.out.println(Msg);
out.println(Msg);
out.flush();
String s = in.readLine();
System.out.println("Echo: "+s);
}
//Serve Side
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
out.flush();
}
private void serve() throws IOException {
while(true){
String s = in.readLine();
System.out.println("Server Received: " + s);
if(s.equals("END"))
break;
System.out.println("Server Send: " + s);
out.println(s);
}
I think what is happening is that when you write your strings, you are pushing them through the ObjectOutputStream, which is attempting to serialize them (I think). You are making things more difficult than necessary. Try using
out = new PrintWriter(socket.getOutputStream());
That will just dump the text directly through the line without all the additional stuff.

Categories