Object streams and Socket network trouble

A

Alex

Using my streams wrong?
Yes. I had similar error.
See, Serialization as any other process waits for EndOfStream. That's
like flag to finish the job. Until it has - it waits.

What I did - I created BreakableStream which inherited and emulated
regular Stream but pretended to be close after recieving
MyOwnEndOfStream flag. For example \r\r.
And all streams I wrapped to this BreakableStream.
Works fine since then.

Alex.
 
E

E.J. Pitt

You need to use ObjectOutputStream.writeUnshared(), otherwise the OOS is
economizing by not resending objects you have already sent even if
they have changed.
 
W

Wouter Groeneveld

Hello all,


The current situation is as following:

class structure:
AbstractPlayer > Player > NetworkPlayer, HumanPlayer, AIPlayer
- Has non-important member vars like int, boolean and such. Also a Robot
wich owns an array of Register objects
a Register object keeps track of 1) a boolean and 2) a Card object.
Game > NetworkGame > NetworkGameClient, NetworkGameServer

Now, everytime the Player.placeYourMove() function has been called, the
representing player's getRobot().Register(x).setCard() gets called and
updates the card the player chose. I'm leaving out all non-important
details, you'll notice soon enough what's troubling me. The most important
part is there's a robot object in player and a register array in robot an a
card in each register.

The client-server structure is roughly a general socketed network
architecture: the server loops trough a player Vector, checks if the player
is a networkplayer instance, and then waits for their move with the
following command:
move = (AbstractPlayer) ((NetworkPlayer)
players.elementAt(i)).getInputStream().readObject()
Where getInputStream returns of course the ObjectInputStream object where
the client and server are connected (created during the server loop while
waiting for clients. This connection should not be broken and is not
generally).
The client has basically the same loop: if player is networkplayer (that
means it's a human or ai player on the server side, OR another networkplayer
but not ourselves) wait for server input, otherwise call the placeYourMove()
locally and send it to the server via writeObject().

Now, everything is fine thanks to the two words 'implements Serializible'.
Except for this:
When the client sends their own AbstractPlayer data, everything is received
successfully and the Robot and other objects are OK. When the server sends
something to the clients (with exact the same call namely
readObject(AbstractPlayer, the changed one)), the move data is received too
but the Robot().Register(x).Card() objects are all null! (in Register
constructor card is null).

I tought hm, an array is not good for patching trough and I made the
Register[] array an Vector or some other data structure. No go. By the way
why does the server receive everything correctly but it gets messed up
otherwise? I tried

--- server sends to clients ---
System.out.println(player.data()); >> prints the RIGHT, changed data info
getOutputStream().writeObject(data);
---

--- client receives from server ---
System.out.println(oldPlayer.data()); >> prints the old data
move = (AbstractPlayer) getInputStream().readObject();
System.out.println(move.data()); >> prints all member vars of the move
correctly except the Register card and boolean.

This basically means move STILL contains the initial registers with the card
object set null and boolean set false in the constructor. This is wrong
because the server is also a player and called locally placeYourMove() to
update his player registers and THEN sent it trough. The println() yust
above the writeObject() method above prints data right so something went
wrong with the streams.
When I alter a testvar, like "boolean test" in AbstractPlayer, in
placeYourMove() and then patch it trough, it is received correctly. Is the
Robot->Register->Stuff tree too messy/wide/deep for object streams?
---

-- server receives from client ---
System.out.println(oldPlayer.data()); >> prints the old data
move = (AbstractPlayer) getInputStream().readObject();
System.out.println(move.data()); >> prints the RIGHT changed data!!!!
---


Woah :-(
What am I doing wrong? Casting wrong? Serializing wrong? Using my streams
wrong? Nope because the server receives everything OK.
Any help?



Thanks a lot in advance!
Greetings
 
E

E.J. Pitt

Wouter said:
To reply myself: I managed to get it working by using

1) out.reset()
2) out.writeUnshared()
and then in.readUnshared()

This is odd, any one of these should do. However there is no network
overhead in doing them all, or anything unsafe.
 
W

Wouter Groeneveld

Hello Alex,

I'm not sure if I understand what you exactly mean. Could you possibily
provide some quick example code?

Thanks a lot in advance!
Greets
Wouter
 
W

Wouter Groeneveld

Hello,


At first I tought "you are my hero!" It looks so obvious. But alas, I
changed writeObject() to writeUnshared() and nothing changed, the client
still receives the not correctly updated AbstractPlayer object....

Are you sure this should work? Could you possibly think of another way why
this doesn't work here?


Thanks a lot!
Greets
Wouter
 
W

Wouter Groeneveld

To reply myself: I managed to get it working by using

1) out.reset()
2) out.writeUnshared()
and then in.readUnshared()


I don't really care if it's network-heavy or an unsafe operation, I've been
trying to fix this stupid "bug" for too long, and it works! Thanks all for
the amazingly fast input!

Greets
Wouter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,054
Latest member
LucyCarper

Latest Threads

Top