Dag: Netzwerkprogrammierung

Wie kann ich ein serialisable Object per UDP übers Netz schicken bzw. ist dies überhaupt möglich?

Danke

  1. Hallo,

    Wie kann ich ein serialisable Object per UDP übers Netz schicken bzw. ist dies überhaupt möglich?

    Ja, per ObjectOutputStream/ObjectInputStream.

    Gruss D@niel

    1. Danke für die Antwort!

      Ja, per ObjectOutputStream/ObjectInputStream.

      Der Konstruktor eines "ObjectOutputStream/ObjectInputStream" möchte, dass ich ihm ein "OutputStream/ObjectInput" mitgebe. Genau an diesem Punkt scheitert es bei mir, weil ich kein "OutputStream/ObjectInput"-Objekt im Angebot habe. Bei einem TCP-Beispiel, das ich gefunden haben sieht das Ganze so aus:

      Socket sock = new Socket(host, port);

      ObjectOutputStream oos = new ObjectOutputStream(sock.getOutputStream());
        ObjectInputSream ois = new ObjectInputStream(sock.getInputStream()

      Für mein UDP verwende ich aber die Klasse "DatagramSocket" anstatt "Socket". Diese bietet aber leider keine Methoden analog zu "getOutputStream()/getInputStream()" an, welche mir meine fehlendes "OutputStream/ObjectInput"-Objekt liefern würde.

      1. Hallo,

        für was möchtest du denn das ganze letzendlich verwenden? Warum gerade DatagramSocket?

        Gruss D@niel

        1. Warum gerade DatagramSocket?

          Ich dachte wenn ich UDP verwende muss ich DatagramSocket verwenden? Dass die Daten mittels UDP verschickt werden sollen ist Vorgabe. Über das Netz geschickt werden jeweils InetAddress-Objekte.

          für was möchtest du denn das ganze letzendlich verwenden?

          Ist eine pseudo-Aufgabe für mein Studium.

          1. Hallo,

            Ist eine pseudo-Aufgabe für mein Studium.

            und zufälligerweise an der Unizh?;-)

            Gruss D@niel

            1. und zufälligerweise an der Unizh?;-)

              Nein. Da hätte uns der Kollege Zufall ja ordentlich an der Nase herumgeführt.

      2. Hallo,

        Für mein UDP verwende ich aber die Klasse "DatagramSocket" anstatt "Socket". Diese bietet aber leider keine Methoden analog zu "getOutputStream()/getInputStream()" an, welche mir meine fehlendes "OutputStream/ObjectInput"-Objekt liefern würde.

        DatagramPacket will ein Byte-Array haben. Ist ja auch logisch, schließlich
        sendet es ganze Pakete, und nicht irgendwelche Streams.

        Was du suchst, ist die Klasse java.io.ByteArrayOutputStream.

        Da du ja was lernen sollst, schreibe ich mal nicht mehr dazu. Lies dich
        mal rein. Falls du nicht weiter kommst, meld dich nochmal.

        Gruß
        Slyh

        1. Was du suchst, ist die Klasse java.io.ByteArrayOutputStream.

          *hat zwei Jahre gebraucht, um die Stream-API zu blicken*

        2. Besten Dank!

          Was du suchst, ist die Klasse java.io.ByteArrayOutputStream.

          In der Tat! Aber gerade zur Osterzeit sind manche Sachen besonders gut versteckt. Vor allem wenn man an der falschen Stelle sucht.

          Falls du nicht weiter kommst, meld dich nochmal.

          Prinzipiell funktioniert die Sache schon, wenn ich die De- und die Serialisierung innerhalb einer Klasse mache keine Schwierigkeiten. Aber wenn ich die Bytes auf die Reise schicke habe ich folgendes Problem:

          ...
            byte data[] = new byte[30000];
            packet = new DatagramPacket(data, data.length);
            fromSocket.receive(packet);
            ByteArrayInputStream bais = new ByteArrayInputStream(packet.getData());
            ObjectInputStream ois = new ObjectInputStream(bais);
            ois.readObject();
            ...

          Hier bleibt er mir immer an der letzten Zeile hängen, mit dieser Meldung:

          java.io.EOFException

          Diese Meldung besagt meinen Infos zufolge

          a) dass das Ende bevor es erwarted wurde erreicht ist;

          oder b) dass ich versucht habe ein Object als primitiven Typ zu deserialisieren (hab ich doch nicht, oder etwa doch?).

          Damit kann ich also nix anfangen. Zunächst dachte ich ja eher, dass ich die Bytes meines serialisierten Objects - auf Senderseite - nicht komplett in ein UDP-Paket reinbekomme. Als ich die Anzahl der Bytes, dann mit

          baos.toByteArray().length   //ByteArrayOutputStream -> baos

          abgefragt habe, lag die gerade mal bei ungefähr 115. da müssten die 30000 empfängerseitig doch gut und gerne hinhauen.

          Danke und Gruss

          1. Hallo,

            ...
              byte data[] = new byte[30000];
              packet = new DatagramPacket(data, data.length);
              fromSocket.receive(packet);
              ByteArrayInputStream bais = new ByteArrayInputStream(packet.getData());
              ObjectInputStream ois = new ObjectInputStream(bais);
              ois.readObject();
              ...

            Hier bleibt er mir immer an der letzten Zeile hängen, mit dieser Meldung:

            java.io.EOFException

            Das Problem wird sein, daß das Byte-Array 30000 Bytes groß ist.

            Ich spekuliere:
            readObject() liest bis zum Ende des Streams -- also bis es ein EOF
            erhält -- und versucht dann ein Objekt aus dem zu bauen, was es da
            gelesen hat. Der ByteArrayInputStream kriegt ein 30000 Bytes großes
            Array, liefert also erst ein "EOF" nachdem alle 30000 Bytes gelesen
            wurden. Daraus kriegt readObject() aber kein Objekt gebaut, weil das
            Array im hinteren Bereich aus Datenmüll (im Java-Fall lauter 0en)
            besteht.

            Lösung: Verwende den ByteArrayInputStream-Konstruktor, bei dem du
            die Länge mit angeben kannst. Die Länge vom DatagramPacket kriegst
            du ja raus...

            Gruß
            Slyh

            1. mittlerweile hat sich das problem erübrigt.

              besten dank für die untersützung!