Socket based PrintWriter doesn't flush, just after close() - java

I am writing a server-client application.
The problem is, that in the server the PrintWriter doesn't flush after some point, just after I close the print writer. But if I close the print writer, it closes the socket as well, however I need to use it later.
How can I solve this?
pw = new PrintStream(socket.getOutputStream());
pw.println("igyulibigyuli");
pw.flush();
It doesn't flush, just if I close the printwriter after the flush.(Or if I close the program!)

The problam was that the socket was busy reading(in a while loop, till it get not null).

Related

Do I need to close the reader of the socket?

So creating a serverside app in Java.
In terms of closing the connection, I'm just wondering what happens if I close the socket before the reader.
For example server side
//imports
public static void main(String[] args) {
Socket socket = null;
try {
ServerSocket servsocket = new ServerSocket(8080);
socket = servsocket.accept();
//connection established
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch(Exception e) {
e.printStackTrace();
} finally {
socket.close();
}
}
Will the bufferedreader instantiated around the input stream from the socket close along with the socket closing, or do I have a potential memory leak on my hands?
Will the bufferedreader instantiated around the input stream from the socket close along with the socket closing
Yes, or rather its underying socket.getInputStream() will close, which the BufferedReader will notice next time you call it.
or do I have a potential memory leak on my hands?
No.
But what you should close is not the socket or the Reader but the outermost Writer or OutputStream that you have wrapped around the socket, to ensure it gets flushed.
Closing either the input or output stream of a socket closes the other stream of the socket, and closing the socket closes both streams.
Will the bufferedreader instantiated around the input stream from the socket close along with the socket closing,
No, since the buffered-reader only holds the stream provided by the socket, it does not know when the state of that stream changes.
or do I have a potential memory leak on my hands?
Not really since the buffer is tied to the lifetime of the reader. Even if closing the reader causes the buffer to be disposed, it would need to wait for garbage-collection to be available for other objects.

does close a socket will also close/flush the input/output stream

I have a program like that,
Socket socket = serverSocket.accept();
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
...some read and write here...
socket.close;
The code works fine. But I am not sure whether the in/out was close if I close the socket or not. Also I didn't call out.flush(), how the data going to be sent out?
Closing the socket doesn't flush the output stream but closes both streams and the socket.
Closing the input stream doesn't flush the output stream but closes both streams and the socket.
Closing the output stream flushes it and closes both streams and the socket.
You should close the outermost OutputStream you have wrapped around the one you got from the socket. For example:
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
DataOutputStream dos = new DataOutputStream(bos);
Close 'dos'. That flushes it, flushes 'bos', and closes everything.
Flush on close is documented in the Javadoc for FilterOutputStream.
Another answer: In Java, when I call OutputStream.close() do I always need to call OutputStream.flush() before?
says that yes! It will be flushed if you close it manually

Android - BufferedOutputStream doesn't flush

I have a problem with a BufferedOutputStream. I want to send a kml file from an Android device to a java server through a socket connection.
(The connection is ok, i am already able to exchange data with a PrintWriter in an other part of my program)
To send my kml file, I fill the buffer. But when i flush() it, nothing happen.
int lu = inFile.read();
while(lu != -1){
out.write(lu);
lu = inFile.read();
}
out.flush();
inFile.close();
inFile is my stream used to read the kml file
out is my BufferedOutputStream using the OutputStream of my socket
I don't close my out object but i don't want to, i don't use it just once. And this is the problem...
The close() method send the buffer's data but close the socket too.
The flush() method does not send the buffer's data.
I want to flush the buffer without closing my socket.
I also tried to use mySocket.shutdownOutput();
int lu = inFile.read();
while(lu != -1){
out.write(lu);
lu = inFile.read();
}
out.flush();
mySocket.shutdownOutput();
inFile.close();
This method close my stream and keep my socket open, that's what i want.
But when i try to open a new output stream, the Exception java.net.SocketException: Socket output is shutdown
So, how to flush my buffer without closing my sokcet are being unable to open a new output stream ?
Socket.close() and Socket.shutdownOutput() both send an EOS to the peer, on which he should close the socket, and after which you can no longer write to the socket, because you've closed it in that direction.
So if you need to continue writing to the socket you cannot use either of these methods.
Probably what you are searching for is a way to delimit application protocol messages. There are at least three techniques:
Send a length word prior to each message.
Send an out-of-band delimiter after each message, i.e. a byte or byte sequence that cannot occur in a message. The STX/ETX protocol, with escapes, is an example of this.
Use a self-describing message format such as Object Serialization or XML. STX/ETX is also an example of this.

Socket close vs Inputstream close

Class c extends thread
static Queue<Socket> socketQueue
Make connection to another server or client
And then add socket to socketqueue
Class a extends thread
method a
bufferedinputstream bis = socketQueue.poll
Do work
Make bis null without closing it<br>
Class b extends thread
Method b
Bufferedinputstream bis = socketqueue.poll
Do work
Make bis null without closing it
I did make bufferedinput stream null since i do not want to close the connected socket. Several posts were telling me that closing input/output stream would close the socket as well.
Whenever I use input/output stream with socket, I usually close stream and socket if its not null.
What I am trying to do here is to make the socket alive and reuse when input or output stream is needed without connecting again.
I tried socket.shutdowninput and output, however, this throws an exception when i make another input/output stream with the socket.
Is there anything I have misunderstood or am missing at this point?
A connection over a socket only ever has one InputStream and one OutputStream. As soon as you close any of those (or the Socket itself) the connection is automatically closed. You need to store the streams you need somewhere and use those, you can not get them from the same Socket each time you need them.

Writing to Socket outputStream w/o closing it

I'd like to write some messages to the server.
Each time, for the tramsmitting only, I'm closing the outputStream and reopen it when I have to send the next message.
os.write(msgBytes);
os.write("\r\n".getBytes());
os.flush();
os.close();
How Can I keep this Socket's OutputStream, os, open and still be able to send the message?
Thanks.
I am missing something here. If you don't call close, it will not close. For example,
os.write(msgBytes);
os.write("\r\n".getBytes());
os.flush();
// Do something
os.write("more message");
os.flush();
// When you are finally done
os.close();
In most protocols, the server accepts som kind of EOF symbol. Send such a symbol instead of closing the stream.
For example, IRC servers interpret "\r\n" as the end of a message. This would be 2 messages on one open OutputStream:
PrintStream printStream = new PrintStream(socket.getOutputStream());
printStream.print("JOIN #channel1\r\n");
printStream.flush( );
printStream.print("JOIN #channel2\r\n");
printStream.flush( );
Also, you should wrap your outputStream with DataOutputStream. This wrapper creates more portable output. Plain OutputStream can cause trouble with certain primitive datatypes if server and client have different computer architectures.
Wrap the Socket's OutputStream in a PrintWriter and call the PrintWriter's println method.
PrintWriter pw = new PrintWriter(socket.getOutputStream());
....
pw.println(message); // call repeatedly to send messages.
....
pw.close(); // when finished writing to server and want to close conn.
I have found the problem and it lays on the client's side.
On the client, I have used -
count = inputStream.read(buffer)) > -1
That means, the client waits till server's outputStream closed, and then processing the incoming data.

Categories

Resources