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.
Related
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
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).
I have two 'Client's, one 'Server' and potentially a 'ThreadManager' that implements runnable.
The two Clients connect with Server via TCP and partake in a protocol handshake/ authentication thing (successful), then I attempted to pass the existing BufferedReaders, DataOutputStreams and Sockets to 'ThreadManager' to manage threading messages between Client1 and Client2:
SERVER:
ThreadManager tManager = new ThreadManager(serviceToClient1, inputStream, outputStream, serviceToClient2, inputStream2, outputStream2);
new Thread(tManager).start();
serviceToClient1.close();
serviceToClient2.close();
THREADMANAGER:
public ThreadManager(Socket cli1, BufferedReader inputStream, DataOutputStream outputStream, Socket cli2, BufferedReader inputStream2, DataOutputStream outputStream2)
{
this.cli1 = cli1;
this.inputStream = inputStream;
this.outputStream = outputStream;
this.cli2 = cli2;
this.inputStream2 = inputStream2;
this.outputStream2 = outputStream2;
}
this constructs successfully, however on .start() called from Server, debugging shows a "Socket Exception: Socket Closed" error as soon the following is called from within ThreadManager:
outputStream.writeBytes("NUMBER: " + i + "\n");
I'm not sure where the problem is created, would I need to close connections and recreate Sockets and streamreaders/writers from within ThreadManager? I tried only passing the Sockets in the ThreadManager constructor and then creating new BufferedReader... etc. but this seems to be just as bad. Could anyone suggest either the solution, or where the problem lies (or both!) :) thanks.
You close your Socket before you try to read from it on your Thread, so you get an exception.
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.
I need to send and receive alternately byte [] using Socket. How to do this ?
What wrappers to use ?
Is this ok or I can do this on quicker way
public boolean SendMessage(byte[] data){
try{
socket = new Socket(ipAddress, port);
OutputStream socketOutputStream = (OutputStream) socket.getOutputStream();
socketOutputStream.write(data);
socket.close();
return true;
}
catch(Exception exc){
System.err.println(exc.getStackTrace());
}
return false;
}
After call of this function I call function for receiving bytes, and again send =>receive and so on. Is there quicker way to do this ?
Use the same socket for reading and writing, just synchronize the two apps so that one read while the other writes, and vice-versa.
Instead of creating a new socket each time for sending/receiving and then closing it, you should use the same socket.
Say, create two threads. One as the SenderThread and the other as ReceiverThread.
The SenderThread creates a socket and then gets the outputstream and you can have a while loop with a flag to indicate whether it should run or not.
Eg: while (running){
The same thing should be done in the ReceiverThread. Create socket and inputstream. Then run the while loop.
In the while loop, you can provide your logic of writing/reading the data to/from the stream.
Use wait and notify so that the threads run in harmony..