# Objekte per TCP verschicken + Thread



## gutenacht-steph (2. Sep 2010)

Hallo,

ich habe folgendes Problem.

Ich besitze einen TCP Clienten und einen TCP Server.

Der TCP Server verschickt an meinen Clienten mittels 

[TCP Server]

```
ObjectOutputStream oos = new ObjectOutputStream(sverb.getOutputStream());
        ObjectInputStream ois = new ObjectInputStream(sverb.getInputStream());

        mr = new MonitorBean();

        oos.writeObject(mr.getTraffic(user, pass));
        oos.writeObject(mr.getMaxTraffic(user, pass));
        oos.writeObject(mr.getIPs(user, pass));
```

Objekte an meinen Clienten.

Diese empfängt mein Client durch

[TCP Client]

```
public void getObjectStreams() throws IOException, ClassNotFoundException {
        oos = new ObjectOutputStream(clientSocket.getOutputStream());
        ois = new ObjectInputStream(clientSocket.getInputStream());

        Traf = (Integer) ois.readObject();
        MT = (ArrayList<String>) ois.readObject();              // erstellt wurden
        IP = (ArrayList<String[]>) ois.readObject();

    }
```

Netbeans regt sich zwar ein bisschen darüber auf mit z.B.,

[XML]TCPClient.java:59: warning: [unchecked] unchecked cast
found   : java.lang.Object
required: java.util.ArrayList<java.lang.String[]>
        IP = (ArrayList<String[]>) ois.readObject();[/XML]

aber es funktioniert auch auf diese Art und Weise.


Ich würde das empfangen beim Clienten, also das getObjectStreams gerne im run() eines Threads erledigen.

Aussehen in meinem TCPClienten würde es dann so:

[TCP Client im "Thread Stil"]

```
public void getObjectStreams() throws IOException, ClassNotFoundException {
        oos = new ObjectOutputStream(clientSocket.getOutputStream());
        ois = new ObjectInputStream(clientSocket.getInputStream());

        new Thread(new Runnable() {

            public void run() {
                try {
                    Traffic = (Integer) ois.readObject();
                    MaxTraffic = (ArrayList<String>) ois.readObject();              // erstellt wurden
                    IP = (ArrayList<String[]>) ois.readObject();
                    
                } catch (IOException ex) {  
                    System.out.println("Fehler aufgetreten");
                 Logger.getLogger(TCPClient.class.getName()).log(Level.SEVERE, null, ex);
                } catch (ClassNotFoundException ex) {
                    Logger.getLogger(TCPClient.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }).start();
    }
```

Das ärgerliche ist, es tritt immer eine Exception auf "Fehler aufgetreten".


```
TCPClient$1 run
SCHWERWIEGEND: null
java.net.SocketException: Socket closed
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:146)
        at java.net.SocketInputStream.read(SocketInputStream.java:199)
        at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2265)
        at java.io.ObjectInputStream$BlockDataInputStream.peek(ObjectInputStream.java:2558)
        at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2568)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1314)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:368)
        at de.genias.mikrotik.verbindungscenter.TCPClient$1.run(TCPClient.java:71)
        at java.lang.Thread.run(Thread.java:636)
```

und die Daten werden vom Server nicht versandt. Das Programm läuft zwar weiter (Client und Server), aber ohne empfangenen Daten.

Woran liegt mein Problem?

Ist mein gecaste die Ursache? Komme leider nicht weiter.

Würde mich über Hilfe sehr freuen.


----------



## XHelp (2. Sep 2010)

Vermutlich beendest du die Verbindung wärend der Thread läuft.
P.S. einfache Zahlen mit ObjektStreams verschicken... hmm....


----------



## SlaterB (2. Sep 2010)

da sind ja ne Menge Methoden, wer ruft denn wann wen wo warum auf, was gehört zu Sender, was zu Empfänger usw.,

wenn eine Methode wie 
> public void getObjectStreams()
mit ihren neu erstellten Streams und der kurze Thread darin beendet sind, 
dann muss man damit rechnen, dass die enthaltenen Streams beendet werden und dies ein close() der Socket-Streams bewirkt,

> new ObjectOutputStream(clientSocket.getOutputStream());
sollte genau einmal recht in der Nähe von clientSocket zentral definiert und solange offen gehalten wie der Socket auch offen ist

was das für Probleme beim Senden mit sich bringt ist eine andere Frage,
vielleicht wird nicht gesendet bevor nicht flush()/ close() aufgerufen wird


----------



## gutenacht-steph (2. Sep 2010)

Schonmal vielen Dank.

Habe im Moment leider keinen Zugriff aufs Programm, aber nur nochmal für das Verständnis.

Die Reihenfolge der Ausführung:

Schritt:
   1.         oos.writeObject(mr.getTraffic(user, pass));  // Server schickt
   2.          Traf = (Integer) ois.readObject();          // Client empfängt

  3.          oos.writeObject(mr.getMaxTraffic(user, pass));   // Server schickt
  4.           MT = (ArrayList<String>) ois.readObject();      // Client empfängt

  5.         oos.writeObject(mr.getIPs(user, pass));   // Server schickt
  6.          IP = (ArrayList<String[]>) ois.readObject();    // Client empfängt


Analog der Code mit dem Thread.

Also der Server beendet die Verbindung denke ich nicht. Ich kann nämlich wie gesagt, weiterhin mit dem laufenden Programm arbeiten und andere Abfragen machen, die mir der Server sauber beantwortet.


----------



## SlaterB (2. Sep 2010)

> der Server beendet die Verbindung denke ich nicht [..] andere Abfragen machen, die mir der Server sauber beantwortet

steht im direkten Widerspruch zur Socket closed-Exception und überhaupt deiner Frage,
es sei denn du hast das berücksichtigt und möchtest ausdrücken dass irgendwie in eine Richttung geschlossen ist und in die andere nicht?
dann solltest du wirklich alles ganz exakt erzählen,
bei deinen Schritten 1-6 ist weder eine Gegenrichtung noch eine auftretende Exception zu sehen und auch nicht wer wo wann Methoden aufruft, die wie gesagt Streams schließen können,

ideal wären eigentlich ein-zwei komplette Programme, vielleicht sogar auf localhost-Socket und damit allgemein überall ausführbar,
oder ein interessantes Log, z.B.


1. oos.writeObject(mr.getTraffic(user, pass)); // Server schickt
2. Traf = (Integer) ois.readObject(); // Client empfängt

3. oos.writeObject(mr.getMaxTraffic(user, pass)); // Server schickt
4. MT = (ArrayList<String>) ois.readObject(); // Client empfängt

5. oos.writeObject(mr.getIPs(user, pass)); // Server schickt
6. IP = (ArrayList<String[]>) ois.readObject(); // Client empfängt

7. Server beendet Methode getObjectStreams() 
8. Server schickt noch was, Client bekommt Exception
9. Client schickt noch was, Sender kann das empfangen

edit:
nochmal genauer dein erstes Posting gelesen:
da steht ja dass es mal geht und mal nicht mehr, na nun bin ich ganz aufgeschmissen worum es dir eigentlich geht,
beim Übergang von Methode zu Thread besteht hier wohl ein wesentlicher Unterschied: der Thread wird erst später ausgeführt, bis dahin ist die Original-Methode fertig und danach wird irgendwo der Socket geschlossen,
deswegen nützen dem Thread die erstellten Streams nicht mehr, die wurden hinterrücks abgeschaltet


----------

