WCM Forum

WCM Forum (http://www.wcm.at/forum/index.php)
-   Programmierung (http://www.wcm.at/forum/forumdisplay.php?f=17)
-   -   Sockets und Java (http://www.wcm.at/forum/showthread.php?t=95017)

blauesau 24.04.2003 17:24

Sockets und Java
 
So, nun mal eine Frage zu Sockets... :D

Ich habe eine Endlosschleife mit der ich auf einkommende Verbindungen warte:

Code:

while(true) {
  socket = new ServerSocket(port);
  new MSSClientThread(instances++, socket).start();
}

Der Thread soll nun so lange laufen, bis der Client die Connection geschlossen hat, oder ein gewisses Timeout abgelaufen ist.

Doch wie stelle ich in dem Thread fest, ob der Client seine Connection geschlossen hat, oder nicht??? :confused:

Code:

public void run() {
  System.out.println("Verbindung aufgebaut: " + instance);

  while(true) {
      try {
        //irgendwas machen...

        if(KEINE VERBINUNG MEHR) {
            socket.close();
            break; //Thread beenden
        }
      }
      catch(Exception ex) {}
  }
}


blauesau 24.04.2003 17:59

Und noch eine Frage hätte ich:

Wie übertrage ich ein ganzes OBJEKT über eine Socketverbindung? Auf der Clientseite müsste ein Objekt erstellt, zum Server geschickt und von diesem 1:1 repliziert werden können, so dass dieser dann Eigenschaften aus diesem Objekt auslesen, bzw auf Methoden zugreifen kann...

Kann mir da wer helfen? :confused:

Tarjan 24.04.2003 19:06

Ad 1) schon mal mit der Methode isConnected() der Klasse Socket versucht?

Mit den beiden Methoden getOutputStream() und getInputStream() bekommst du einen Input- bzw Output Stream. Direkte Subklassen von denen ist ObjectInputStream bzw. ObjektOutputStream mittels denen du Objekte serialisieren kannst solange sie das Interface Serializable implementieren. Und damit kannst du Objekte über Sockets verschicken.

Siehe dazu auch: http://java.sun.com/docs/books/tutor...ngWriting.html
bzw. das ganze Tutorial über Sockets: http://java.sun.com/docs/books/tutor...ets/index.html

blauesau 24.04.2003 19:12

Da bin ich auch kurz nach dem Posten draufgekommen :rolleyes: , aber es gibt eh immer noch ein (ok, wäre schön, wenn es nur eines wäre... ;) ) Problem:

Sagen wir ich verschick ein Objekt vom Typ JPanel... Alles kein Problem, NUR... wie mach ich auf der Empfängerseite wieder ein JPanel draus?

Ich habe es mit
Code:

    JPanel o = (JPanel) oinput.readObject();
                        ^^^^^^
                        ObjectInputStream

und dergleichen versucht, das hat aber leider nicht wirklich funktioniert...

Wenn man aber
Code:

    System.out.println(oinput.readObject());
ausführt, stellt man fest, dass das Versenden an und für sich schon funktioniert...

Tarjan 24.04.2003 19:35

Habe mir das mal kurz ind der Java API angeshen. An und für sich müsste es genauso funktionieren. JPanel ist Serializable, und mittels readObject bekommst auch das Objekt.

Was funktioniert denn nicht?

Versuche erst einmal einfacher Objekte (Value Objekte wie zB. eine HashMap mit Werten) zu verschiocken. Da kannst du die Werte direkt überprüfen.

blauesau 24.04.2003 20:42

Ich glaub's nicht... Aufeinmal funktioniert das und ich hab (glaub ich *g*) nichts verändert... :eek:

Vorher hat er sich zur Laufzeit furchtbar echauffiert, er könne dieses Objekt nicht casten...

Tjo... :bier:

Vielen Dank jedenfalls. Und keine Angst, ich komme wieder! :D :D

blauesau 24.04.2003 21:15

Langsam wird mir die Fragerei peinlich... :o

Erstmal Code (Kot?):

Code:

import java.net.*;
import java.io.*;
import javax.swing.*;

public class MSSClientThread
    extends Thread {
  protected int instance;
  protected Socket socket;

  public MSSClientThread(int inst, Socket sock) {
    instance = inst;
    socket = sock;
  }

  public void run() {
    InputStream input = null;
    ObjectInputStream oinput = null;

    System.out.println("(" + instance + ") Verbindung aufgebaut");

    try {
      input = socket.getInputStream();
      //oinput = new ObjectInputStream(input);
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }

    while (true) {
      try {
        oinput = new ObjectInputStream(input);
       
        JPanel o = (JPanel) oinput.readObject();

        System.out.println("(" + instance + ") " + o.getLocation().x);

        if (input.read() == -1) {
          System.out.println("(" + instance + ") Verbindung beendet");
          socket.close();
          break;
        }
      }
      catch (Exception ex) {
        ex.printStackTrace();
        break;
      }
    }
  }
}

Was hätte ich gerne? Der Client schickt an diesen Thread ein Objekt (in diesem Fall, beispielsweise vom Typ JPanel, wie auch immer...). Der Server (Thread) liest die x-Koordinate aus und gibt sie aus. Dann soll er auf weitere Incomings warten, bis es zu einer Abbruchbedingung kommt. Funktioniert auch - aber nur einmal! Versuche ich mit dem Client noch einmal zu senden, kommt es beim Server zu dieser Fehlermeldung:

Code:

java.io.StreamCorruptedException: invalid stream header
        at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:737)
        at java.io.ObjectInputStream.<init>(ObjectInputStream.java:253)
        at sic.MSSClientThread.run(MSSClientThread.java:39)

MSSClientThread.java:39 bezieht sich dabei auf die rot eingefärbte Zeile...

Flink 25.04.2003 12:30

Unter Java-API steht, dass der Client den Header 'has written and flushed the header' . Offenbar hat der Client den Header nicht ganz rausgeschrieben, was man in diesem Listing aber nicht sieht.

blauesau 25.04.2003 13:10

Hi!

Der Client-Code sieht ungefähr so aus:

Verbindung herstellen
Code:

void jButton1_actionPerformed(ActionEvent e) {
    try {
      socket = new Socket("localhost", 5190);
    }
    catch (IOException ex) {
      ex.printStackTrace();
    }
  }

Objekt senden
Code:

  void btnSend_actionPerformed(ActionEvent e) {
    JPanel objekt = new JPanel();

    objekt.setLocation(10,10);
    try {
      out = socket.getOutputStream();
      oout = new ObjectOutputStream(out);

      //ObjectOutputStream oout = socket.getOutputStream();
      oout.writeObject(objekt);
      //oout.writeObject(null);
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }
  }


blauesau 25.04.2003 13:23

Die Methode run() vom Server-Thread:

Code:

public void run() {
    InputStream input = null;
    ObjectInputStream oinput = null;

    System.out.println("(" + instance + ") Verbindung aufgebaut");

    try {
      input = socket.getInputStream();
      oinput = new ObjectInputStream(input);
    }
    catch (Exception ex) {
      ex.printStackTrace();
    }

    JPanel o;

    Object ob = null;
    try {
      while (true) {
        if ((ob = oinput.readObject()) == null) {
          System.out.println("NULL");
          break;
        }
        else {
          System.out.println(ob.toString());
          oinput = new ObjectInputStream(input);
        }

      }

      System.out.println("(" + instance + ") Verbindung beendet");
      oinput.close();
      input.close();
      socket.close();

    }
    catch (Exception ex1) {
      ex1.printStackTrace();
      //System.out.println(ob.toString());
    }
  }



Alle Zeitangaben in WEZ +2. Es ist jetzt 14:21 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
© 2009 FSL Verlag