Java Creating a new ObjectInputStream Blocks
When you construct an ObjectInputStream
, in the constructor the class attempts to read a header that the associated ObjectOutputStream
on the other end of the connection has written. It will not return until that header has been read. So if you are seeing the constructor 'hang', it's because the other side of the socket either hasn't used an ObjectOutputStream
, or hasn't flushed the data yet.
new ObjectInputStream() blocks
You need to create the ObjectOutputStream
before the ObjectInputStream
at both sides of the connection(!). When the ObjectInputStream
is created, it tries to read the object stream header from the InputStream
. So if the ObjectOutputStream
on the other side hasn't been created yet there is no object stream header to read, and it will block indefinitely.
Or phrased differently: If both sides first construct the ObjectInputStream
, both will block trying to read the object stream header, which won't be written until the ObjectOutputStream
has been created (on the other side of the line); which will never happen because both sides are blocked in the constructor of ObjectInputStream
.
This can be inferred from the Javadoc of ObjectInputStream(InputStream in)
:
A serialization stream header is read from the stream and verified. This constructor will block until the corresponding ObjectOutputStream has written and flushed the header.
This is also described in section 3.6.2 of Fundamental networking in Java by Esmond Pitt.
new ObjectInputStream blocks despite flushing OutputStream
The line of code you indicate will block until the peer has created an ObjectOutputStream
on its socket, or written something else to the socket (which will cause a StreamCorruptedException
).
The program stops when the ObjectInputStream object is created
You essentially have a deadlock here. If you start the server first, it will start listening for connections on port 9998. When you then start the client, it makes a connection to the server. The server accepts the connection, and tries to create an ObjectInputStream
. The ObjectInputStream
constructor (and the server thread) will block until it can read a stream header from the client (which the client hasn't sent yet). So the server doesn't get to the point where it creates an ObjectOutputStream
(which would cause data to be sent to the client).
Meanwhile the client is attempting to create an ObjectInputStream
and will block because the server hasn't yet sent any data. The result is two threads blocked in the ObjectInputStream
constructor.
The solution is quite simple - in the server, create the ObjectOutputStream
first, then create the ObjectInputStream
:
socket = new Socket("localhost", 9998);
output = new ObjectOutputStream(socket.getOutputStream());
input = new ObjectInputStream(socket.getInputStream());
ObjectInputStream blocks on initialization Sockets
Try call socket.getOutputStream()
before getInputStream
in server side code.
.
ObjectInputStream block my socket
Your client isn't constructing an ObjectOutputStream
, so your ObjectInputStream
constructor is blocking for reasons explained in the Javadoc.
Create ObjectInputStream according to a socket
The peer needs to create his ObjectOutputStream
immediately on connection. Otherwise new ObjectInputStream
will block until he does so.
It would be better if you could defer creation of the ObjectInputStream
to the run()
method of the thread that handles the accepted socket. You shouldn't do any I/O in the accept loop, just the accept itself. Otherwise you can block subsequent clients.
ObjectInputStream blocks forever during readObject()
You can't use multiple streams over the same socket in general. There are specific cases where it works but in general you're up against unknown buffering which will get your peers out of sync quick as a wink. Redo it with a single ObjectOutputStream
and ObjectInputStream
at each end. If you only need to encrypt certain parts of the stream, look into SealedObject
.
Related Topics
Difference Between Static and Final
How to Prevent Eclipse from Hanging on Startup
Annotation to Make a Private Method Public Only for Test Classes
Copying Text to the Clipboard Using Java
Which Loop Has Better Performance? Why
Spring - Injecting a Dependency into a Servletcontextlistener
Tomcat - Maxthreads VS Maxconnections
@Generatedvalue Polymorphic Abstract Superclass Over MySQL
Any Good Recommendations for Mp3/Sound Libraries for Java
Is -Djava.Library.Path=... Equivalent to System.Setproperty("Java.Library.Path", ...)
How to Obtain the Start Time and End Time of a Day
How to Debug a Multi-Threaded App in Intellij
Accessing Constructor of an Anonymous Class
Which Part of Throwing an Exception Is Expensive