Why does flush() effect println() on PrintWriter - java

I have the basic code for a server:
ServerSocket serverSocket = new ServerSocket(14000);
Socket clientSocket = serverSocket.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
String incoming;
while((incoming = in.readLine()) != null){
System.out.println("Client Says: " + incoming);
out.println("Client Says: " + incoming);
out.flush();
//if(incoming.equals("HELLO")) break;
}
clientSocket.close();
serverSocket.close();
I'm trying to further understand streams as they're giving me some serious headaches. From what I've read, println methods automatically flush for you, however this line is not delivered to the client unless the flush method is called afterwards? I'm just looking for a nice solid explanation of this?

To enable automatic flushing of the PrintWriter, the second argument of its constructor must be set to true.

I had this issue before, just:
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
That will make the difference. If you do not autoflush you can get some errors or receive data as null, it happened to me some time ago. Best regards.

Related

Cannot receive from client socket in a loop [duplicate]

This question already has answers here:
Java - Understanding PrintWriter and need for flush
(2 answers)
Closed 6 years ago.
I am trying to make a simple quiz between client and server. The server sends an array of questions and waits for a reply from client. The problem is that the client side does not display the array from server nor can take any input. The server has definitely connected to the client, but the client side stays idle.
Server:
OutputStream o =sock.getOutputStream();
PrintWriter pw = new PrintWriter(o);
InputStream is = sock.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
int i=0;
while(i<10)
{
pw.println(array[i]);
String st = br.readLine();
System.out.println(st);
i++;
}
Client:
InputStream istream = sock.getInputStream();
BufferedReader content = new BufferedReader(new InputStreamReader(istream));
String str;
OutputStream ostream=sock.getOutputStream();
PrintWriter pw = new PrintWriter(ostream)
String ans;
for(int j=0;j<10;j++)
{
str=content.readLine();
System.out.println(str);
ans=sc.nextLine();
pw.println(ans);
}
PrintWriter#println doesn't flush text to client by default so you need to call pw.flush() manually each time you want to ensure sending.
To let println automatically flush text to client use PrintWriter(Writer out, boolean autoFlush) constructor with autoFlush parameter set as true, like
PrintWriter pw = new PrintWriter(o, true);
since PrintWriter(OutputStream out) constructor internally invokes this(out, false); so automatic flash is disabled println, printf or format methods.
PrintWriter doesn't flush information itself by default.
You should either add: pw.flush() after pw.println(ans) or create your writer in that way: PrintWriter pw = new PrintWriter(o, true);

Java Sockets writing/reading

So I want to read from socket , but it doesn't gives me anything , I am newbie to java networking so please help me , it doesn't gives me any errors but doesn't gives me any output from client socket too... here is a source code:
ServerSocket server = new ServerSocket(4444);
Socket client = server.accept();
PrintWriter out = new PrintWriter(client.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String inputline = in.readLine();
while(inputline != null)
{
System.out.println("recieved "+inputline);
}
out.close();
in.close();
server.close();
client.close();
You call readLine() exactly once. If it's not null on the first iteration, you've got an infinite loop (because it will forever be non-null). Be sure to update it.

Can't use InputStream from Socket after writeObject

Here is the situation:
I have a ServerSocket ss, and "Socket socket = ss.accept();", then if I do this:
istream = socket.getInputStream();
ostream = socket.getOutputStream();
in = new BufferedReader(new InputStreamReader(istream));
out = new PrintWriter(new BufferedOutputStream(ostream));
/*
I use in/out few times
everything OK
*/
ObjectOutputStream oos = new ObjectOutputStream(ostream);
oos.writeObject(someobject);
/* probably code that solves the problem */
String line = in.readLine();
On the client side I have this code:
PrintWriter out = new PrintWriter(new BufferedOutputStream(socket.getOutputStream()),true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
/*
using in/out, no problems
*/
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
SomeObject so = (SomeObject)ois.readObject();
out.println("some text");
Everything is OK, until I send someobject. Client recieves object properly, no problems there. But I can't use socket anymore. If I do oos.close(), I get Exception that says "socket closed". If I do oos.reset() I get Exception with similar message. "socket reset". So what should I do? Is it possible to use same input and output streams after writeObject()?
What happens when I send "some text" is that I'm just getting nulls no matter how many times I call readLine(), I never get that "some text".
You can't use multiple type of stream/reader/writer on the same underlying socket. All your streams and readers and writers are buffered so they will all get thoroughly mixed up. Stick tone kind. Stick to one protocol. If you have object streams, use them for everything. And create them once for the life of the socket, not per message.

Sending a JSON object over TCP with Java

I'm trying to replace a Netcat command that I'm running in my terminal that will reset some data on a server. The netcat command looks like this:
echo '{"id":1, "method":"object.deleteAll", "params":["subscriber"]} ' | nc x.x.x.x 3994
I've been trying to implement it in Java since I would like to be able to call this command from an application I'm developing. I'm having issues with it though, the command is never executed on the server.
This is my java code:
try {
Socket socket = new Socket("x.x.x.x", 3994);
String string = "{\"id\":1,\"method\":\"object.deleteAll\",\"params\":[\"subscriber\"]}";
DataInputStream is = new DataInputStream(socket.getInputStream());
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
os.write(string.getBytes());
os.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
The code also hangs on the while loop that should read the InputStream, I have no idea why. I've been using Wireshark to capture the packets and the data that is going out looks the same:
{"id":1,"method":"object.deleteAll","params":["subscriber"]}
Perhaps the rest of the packets are not shaped in the same way but I really can't understand why that would be. Perhaps I am writing the string in a faulty way to the OutputStream? I have no idea :(
Note that I posted a question similar to this yesterday when I didn't properly understand the problem:
Can't post JSON to server with HTTP Client in Java
EDIT:
These are the possible results I get from running the nc command, I would expect to get the same messages to the InputStream if the OutputStream sends correct data in a correct way:
Wrong arguments:
{"id":1,"error":{"code":-32602,"message":"Invalid entity type: subscribe"}}
Ok, successful:
{"id":1,"result":100}
Nothing to delete:
{"id":1,"result":0}
Wow, I really had no idea. I experimented with some different Writers like "buffered writer" and "print writer" and it seems the PrintWriter was the solution. Although I couldn't use the PrintWriter.write() nor the PrintWriter.print() methods. I had to use PrintWriter.println().
If someone has the answer to why other writers wouldn't work and explain how they would impact the data sent to the server I will gladly accept that as the solution.
try {
Socket socket = new Socket(InetAddress.getByName("x.x.x.x"), 3994);
String string = "{\"id\":1,\"method\":\"object.deleteAll\",\"params\":[\"subscriber\"]}";
DataInputStream is = new DataInputStream(socket.getInputStream());
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
PrintWriter pw = new PrintWriter(os);
pw.println(string);
pw.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
I think the server is expecting newline at the end of the message. Try to use your original code with write() and add \n at the end to confirm this.

Java: BufferedReader and OutputStream

I've got the following code, I'm trying to send data text by sockets. But when I try to send via PrintWriter, my client does nothing and it stops at in.readLine(). However when I use simply OutputStream and send it as bytes, my client doesn't have any problem with reading. Is it possible to as I want ?
out = new PrintWriter(sock.getOutputStream());
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
while (true) {
System.out.println("SERVER-THREAD: IP "
+ sock.getInetAddress().getHostAddress());
out.write(marshall() + "\n");
Thread.sleep(1000);
}
//Client
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
out = new PrintWriter(sock.getOutputStream());
while (updateList) {
System.out.println("Before");
String inputip = in.readLine();
System.out.println("CLIENT: " + inputip);
//unmarshall(in);
System.out.println("After");
Thread.sleep(1000);
}
PrintWriter buffers the data to be written so it will not do so until the buffer is full. You need to call flush here
out.flush();
When you perform a readLine() it waits until it has a read a whole line. i.e. a new line.
Your send is sending text without a newline so the receive waits for something which will not happen.
A more basic problem is that you are mixing text and binary which is more likely to confuse than be useful.
I suggest you write text with PrintWriter.println() which you can read with BufferedReader.readLine().

Categories

Resources