# Problem mit Server/Client mit ObjectOutputStream



## webhalf (10. Dez 2008)

Moin Moin ^.^


ich habe folgendes problem
ich versuche folgendes objekt (MyObject) über das netzwerk mittels ObjectOutputStream zu versenden.


```
import java.io.Serializable;

class MyObject implements Serializable {
  private int a=0;
  public MyObject(int a){
    this.a=a;
  }
  public int getA(){
    return this.a;
  }
  public void setA(int a){
    this.a=a;
  }
}
```

das funktioniert derzeit auch sehr gut.

so... nun erklär ich erstmal was mein server macht ;-)
er erstelt alls erstes nur ein objekt von MyObject und wartet dann auf eingehende verbindungen
sobalt eine eintrifft, wird der integewert im objekt erhöht und ein ServerThread gestartet, der dem client die ganze zeit das objekt senden...
nun kommt das problem was ich habe
sobald ein zweiter client eine verbindung aufbaut, wird zwar der integerwert erhöht und auch dem neuen clienten zugesandt,... dem vorherigen clienten jedoch wird noch das alte objekt zugesandt.....
sprich, der neue erhält die intzahl 2... der alte noch die intzahl 1

ich geh mal von aus, dass der serverthread sich immer das aktuelle objekt vom server holt udn es hinüber sendet....
da brauch ich nun hilfe ^.^


hier der rest des codes (server, serverthread und client)


```
import java.io.*;
import java.net.*;
import java.util.*;

public class Server {
  MyObject _mo;

  public Server(){
    this._mo=new MyObject(0);
  }
  public synchronized MyObject getMO(){
    return _mo;
  }
  public static void main(String[] args) {
    Server s = new Server();
    s.doStart();
  }
  private void doStart(){
    ServerSocket serverSocket=null;

    try {
      serverSocket = new ServerSocket(4444);
      Socket socket=null;
      while(true){
        System.out.println("warte auf eingehende verbindung");
        socket = serverSocket.accept();
        System.out.println("eingehende verbindung akzeptiert");
        MyObject m = this.getMO();
        m.setA(m.getA()+1);

        new ServerThread(this,socket).start();
        System.out.println("ServerThread gestartet\n");
      }
    } catch(Exception e){
      System.out.println("Exception -> "+e.getMessage());
      e.printStackTrace();
    }
  }
}
```


```
import java.io.*;
import java.net.*;

class ServerThread extends Thread {
  private MyObject _mo;
  private Socket _socket;
  private Server _s;

  public ServerThread(Server s,Socket so){
    this._s=s;
    this._socket=so;
  }
  public void run(){
    try {
      boolean runST=true;
      ObjectOutputStream out = new ObjectOutputStream(this._socket.getOutputStream());

      while(runST){
        out.writeObject(_s.getMO());
        out.flush();

        try {
          this.sleep(1000);
        } catch(InterruptedException e){
          System.out.println("ServerThread -> InterruptedException");
        }

      }
    } catch(IOException e){
      System.out.println("ServerThread -> run() -> IOException");
      e.printStackTrace();
    }
    try {
      this._socket.close();
    } catch(Exception e) {
      System.out.println("ServerThread -> run() -> socket.close()");
      e.printStackTrace();
    }
  }
}
```


```
import java.io.*;
import java.net.*;
import java.util.*;

public class Client {

  public static void main(String[] args) {
    MyObject mo;
    try {
      System.out.println("verbinden mit localhost");
      Socket socket = new Socket( "127.0.0.1", 4444 );
      System.out.println("--- in erstellen!!!");
      ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
      System.out.println("--- in erstellt");

      while(true){
        mo = (MyObject)in.readObject();
        System.out.print("MyObject - anz: ");
        System.out.println(mo.getA());
        

      }


    } catch(Exception e){
      System.out.println("Exception: "+e.getMessage());
      e.printStackTrace();
    }


  }
}
```

mfg
Webhalf


----------



## SlaterB (10. Dez 2008)

lustig, dazu hat gerade jemand anders vor kurzem erst einen Link gepostet, vorher wußte ich das auch nicht:

http://www.javaspecialists.eu/archive/Issue166.html


> Here is a rule to remember: Never serialize mutable objects. We could relax this rule a little bit to: Don't re-serialize modified objects without first resetting the stream. Another approach is to always copy mutable objects before serialization. None of these relaxations will necessarily give you the intended behaviour.


da du kaum einen neuen ObjectOutputStream aufmachen kannst,
bleibt wohl nur reset() oder Objekt kopieren

ersteres funktioniert bei mir auch in diesem Fall


----------



## tuxedo (10. Dez 2008)

Glaub das könnte ich gewesen sein ;-)

- Alex


----------



## HoaX (10. Dez 2008)

ich versteh die fage nicht ganz. welches verhalten willst du erreichen?

so stehts ja im code. für jeden client wird die zahl um 1 erhöht und der  neue wert zugesand.

client1 bekommt 1, client 2 die 2, ....


----------



## SlaterB (10. Dez 2008)

> Glaub das könnte ich gewesen sein 

ich hatte den Hobbit in Erinnerung, aber auch so gut 
ich wußte schon, dass ich keinen Namen erwähnen sollte 

-------

@Hoax:
jeder Client soll den aktuellsten Wert 2 erhalten,
im Server-Objekt steht ja auch 2 und es gibt nur ein Server-Objekt,

im OutputStream-Cache ist das alte Objekt mit Wert 1 enthalten


----------



## webhalf (10. Dez 2008)

jo das mit dem reset funktioniet
aber jedesmal ein erset durchführen ist ja auch blöd hm.......

@Hoax
SlaterB hat recht 
jeder sollte den aktualisierten wert bekommen ...

das programm da oben war nur ein test, denn in einem größeren programm funktionierte es auc nicht  und dann reduziert man es halt auf den fehler und testet mit herum und wundert sich ^.^


dann dankeschön ;-)
werd mir auch mal die anderen sachen von javaspecialists.eu durchlesen


----------

