ObjectStream's quer durch's Internet

Moin

Ich kämpfe gerade mit einem „komischen“ Effekt. Dazu ein Beispiel:

public class Dummy {

public boolean OK;
}

(…)

ObjectOutputStream OOUT = new ObjectOutputStream (new Socket(IP,Port).getOutputStream());
Dummy D = new Dummy ();
D.OK = true;
OOUT.writeObject (D); //(1)
D.OK = false;
OOUT.writeObject (D); //(2)

(…)

Bei (1) schickt der Stream ein Dummy-Objekt korrekt zum Empfänger. Bei (2) kommt ein zweites Dummy-Objekt an allerdings mit OK = true obwohl OK auf false gesetzt wurde in der Zeile davor.

Meine Fragen:

  1. Wieso ist das so ?
  2. Gibt es eine Möglichkeit ausser ObjectOutputStream.reset() diesen Effekt loszuwerden ?

Danke.

Moin,

Bei (1) schickt der Stream ein Dummy-Objekt korrekt zum
Empfänger. Bei (2) kommt ein zweites Dummy-Objekt an
allerdings mit OK = true obwohl OK auf false gesetzt wurde in
der Zeile davor.

  1. Wieso ist das so ?

Vielleicht liegt das Objekt noch im Buffer und wird nicht wirklich übertragen. Ich halte die Vorgehensweise auch für einen Fehler: Du solltest eine übertragenes Objekt nicht ändern, sondern die Referenz löschen. Andernfalls hast Du ein Objekt, daß auf verschiedenen Hosts verschiedene Zustände hat.

Thorsten

Moin

Vielleicht liegt das Objekt noch im Buffer und wird nicht
wirklich übertragen. Ich halte die Vorgehensweise auch für
einen Fehler: Du solltest eine übertragenes Objekt nicht
ändern, sondern die Referenz löschen. Andernfalls hast Du ein
Objekt, daß auf verschiedenen Hosts verschiedene Zustände hat.

Doch, muss ich. Der eine Host spielt Server und schickt eine „aktuelle“ Version des Object etwa 2x pro Minute an alle Clients. Die bekommen aber immer nur die erste Version.

Die Clients überschreiben natürlich die alte Version.

Das Object jedesmal neu zu erstellen wär ein echtes Problem, ich bekomme das „Orginal“ von einem anderen Program desen Source ich nicht hab.

Moin,

Vielleicht liegt das Objekt noch im Buffer und wird nicht
wirklich übertragen. Ich halte die Vorgehensweise auch für
einen Fehler: Du solltest eine übertragenes Objekt nicht
ändern, sondern die Referenz löschen. Andernfalls hast Du ein
Objekt, daß auf verschiedenen Hosts verschiedene Zustände hat.

Das Object jedesmal neu zu erstellen wär ein echtes Problem,
ich bekomme das „Orginal“ von einem anderen Program desen
Source ich nicht hab.

Dann paßt Dein Code nicht. Such mal ein anderes Beispiel.

Du kannst auch mal nach irgendwelchen Flush-Geschichten suchen,
mit denen Du den Stream leeren kannst.

Mich interessiert die Geschichte auf jeden Fall, ich muß
vielleicht bald ein paar Objekte durch die Gegend schicken und
wir wissen noch nicht genau, welche Technologie wir benutzen.

Thorsten

Servus,

Vielleicht liegt das Objekt noch im Buffer und wird nicht
wirklich übertragen.

Ersteres ist auch meine Meinung. Deswegen solltest du es mal versuchen, den Ausgabepuffer zu löschen.

Versuchs doch mal mit

ObjectOutputStream OOUT = new ObjectOutputStream (new Socket(IP,Port).getOutputStream());
Dummy D = new Dummy ();
D.OK = true;
OOUT.writeObject (D); //(1)

// Ausgabestrom auch wirklich rausschreiben.
OOUT.flush();

D.OK = false;
OOUT.writeObject (D); //(2)

Dirk

Moin

Ersteres ist auch meine Meinung. Deswegen solltest du es mal
versuchen, den Ausgabepuffer zu löschen.

// Ausgabestrom auch wirklich rausschreiben.
OOUT.flush();

Das Object kommt zwar schneller an, ist aber immernoch „falsch“.

Trotzdem danke.

Hallo,

ich denke das du das objekt erst serialiseren mußt. Am besten du verpackst da zu versendend Objekt in einem andern das dann serialisert wird.

public class SendeContanire implements Serializable
{ public void setObjekt(Object obj)
{ Object o = obj;
}
public Object getObjekt()
{ return o;
}
}

Anschließend muß auf dem Client das die Sache wieder deserzalisiert werden.

Einen interessanten Aktikel von SUN findest du dazu hier
http://java.sun.com/jdc/JDCTechTips/2001/tt0327.html

gruß Thomas

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Moin,

ich denke das du das objekt erst serialiseren mußt. Am besten
du verpackst da zu versendend Objekt in einem andern das dann
serialisert wird.

public class SendeContanire implements Serializable
{ public void setObjekt(Object obj)
{ Object o = obj;
}
public Object getObjekt()
{ return o;
}
}

Fehlt da noch etwas? Soviel ich weiß, ist ‚Serializable‘ nur
ein Flag, die Arbeit bleibt an Dir hängen.

Thorsten

Moin

ich denke das du das objekt erst serialiseren mußt. Am besten
du verpackst da zu versendend Objekt in einem andern das dann
serialisert wird.

public class SendeContanire implements Serializable
{ public void setObjekt(Object obj)
{ Object o = obj;
}
public Object getObjekt()
{ return o;
}
}

Anschließend muß auf dem Client das die Sache wieder
deserzalisiert werden.

… ok, ich hab das „implements Serializable“ beim Beispiel vergessen. Das ist aber nicht das Problem.

Das Object kommt ja an… nur nicht in dem aktuellen Status.

(übrigens, wenn wir es schon so genau nemmen:
Das Verpacken in einen Wrapper hift bei Not-Serializable-Execptions auch nichts.)

Einen interessanten Aktikel von SUN findest du dazu hier
http://java.sun.com/jdc/JDCTechTips/2001/tt0327.html

Der Artikel dreht um RMI, soviel Bandbreite hab ich aber nicht zur Verfügung.

Danke trotzdem.

Hallo

Dann paßt Dein Code nicht. Such mal ein anderes Beispiel.

Das Org. hat etwa 500 KB und ist ein Betriebtsgeheimnis.

Du kannst auch mal nach irgendwelchen Flush-Geschichten
suchen,
mit denen Du den Stream leeren kannst.

mit .reset() kann man sich behelfen… das lässt dann aber die Bandbreite zusammenbrechen.

Mich interessiert die Geschichte auf jeden Fall, ich muß
vielleicht bald ein paar Objekte durch die Gegend schicken und
wir wissen noch nicht genau, welche Technologie wir benutzen.

Als allgemeiner Rat:
nimm nicht java.

und wenn dann sorg für viel Bandbreite.

Moin

Fehlt da noch etwas? Soviel ich weiß, ist ‚Serializable‘ nur
ein Flag, die Arbeit bleibt an Dir hängen.

nein, in dem Punkt hat er Recht. die JVM (der Stream) übernimmt die Arbeit. Ich hab’s nur im Beispiel vergessen.

cu