I'm trying to create a multiplayer game, who runs on the internet. The problem is that I'm trying to get input on a stream and for some reason I can't make 2 streams with one socket, and I'll explain:
Socket s=new Socket("127.0.0.1",5001);
ObjectInputStream obj1=new ObjectInputStream(s.getInputStream());
ObjectInputStream obj2=new ObjectInputStream(s.getInputStream());
Can someone explain me why this code snippet isn't working?
Edit: Here's another example for code sample that isn't working.
while (true) {
try {
objI = new ObjectInputStream(sock.getInputStream());
objO = new ObjectOutputStream(sock.getOutputStream());
}catch(Exception e) {
e.printStackTrace();
}
}
Edit 2: thanks very much for answering. I tried to flush the objects, but I keep getting this error:
java.io.StreamCorruptedException: invalid stream header: 33740003
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at Proccess.run(Proccess.java:22)
at java.lang.Thread.run(Unknown Source)
Streams are stateful - when you read from a stream, you are reading from some position in the stream, and by doing that you change the position.
If two things (like you're two wrapper ObjectInputStreams) are reading from the underlying stream at the same time, they will both try to change the position within the stream, but neither one knows what the other is doing. So reading from one changes the position, and then the other one expects the stream to be where it left it, but it is not.
Imagine you were getting this answer as words written on separate pieces of paper, being given to you one-by-one. But while you are reading the pieces of paper, somebody else is taking some of them away before you have seen them - what you got would not make sense. That is what is happening - one stream takes away parts of the data, and when the other stream looks at the data again, some of it is missing, consumed by the other stream.
Have one ObjectInputStream that reads incoming objects. If you want to publish those objects to multiple consumers, create a collection of things to send the incoming objects to, and iterate over them and pass the new object to each one.
Socket is a full duplex pipe. It has one input stream and one output stream. To have multiple stream, you should build a multiplexing protocol upon on it(TCP).
Without knowing the error message, what should happen with your code, is that you always get the same input/output stream and you should hang when trying to get the ObjectInputStream
.
This is due to the fact, that for some reason, a newly created ObjectInputStream
needs to talk to the corresponding ObjectOutputStream
and waits for it to connect.
I always use the follwoing code:
Socket socket = new Socket("localhost", 12345);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.flush();
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
With the call to flush
the input stream on the other side of the socket is happy and continues.
EDIT, regarding your Edit2:
That looks like the second ObjectOutputStreams writes some metadata to the stream that the first InputStream reads (or vice versa). That metadata is interpreted as inconsistency and the exception is thrown.
You should really have only one in- and one output stream opened per socket and overlay each with one ObjectStream. If you need more streams open more sockets. Depending on your system you can have a few 100 of them opened simultaneously (if you really need this...)