# Objekte verschicken



## jma (26. April 2005)

Moin
hab bei "java ist auch eine insel" gelesen das man Objekte übers Netz verschicken kann, dazu das folgende Beispiel auf der client seite:
....
Socket s = new Socket( "host", port );
OutputStream os = s.getOutputStream()
ObjectOutputStream oos = new ObjectOutputStream( os );
oos.writeObject( object );
...
Würde nun ganz gerne eigene Objekte damit übertragen. Leider wurde die Serverseite nicht weiter erklärt sondern nach RMI verwiesen. Wenn ich aber "MeinObjekt" sowohl auf server wie auch client seite habe, müßte es doch möglich sein mittels ObjectInputStream und InputStream das gesendete Objekt zu empfangen. 

Hat jemand schon mal damit gearbeitet?, bzw hat vielleicht jemand dazu nen codebeispiel oder nen guten Internetlink? Aufbau der Netzwerkkommunikation etc ist bekannt, geht halt speziell um das verschicken von Objekten übers Netz.

Besten Dank  für eure Hilfe
jma


----------



## Thomas Darimont (26. April 2005)

Hallo!

Klassen deren Instanzen du durch einen ObjectOutputStream schicken willst müssen das Serializable MarkerInterface implementieren. Weiterhin muss du sicherstellen, dass sowohl Client als auch Server den Typ der Klasse kennen welchen du versenden willst.

Bsp.:

```
/**
 * 
 */
package de.tutorials;

import java.io.Serializable;

/**
 * @author Tom
 */
public class SomeObject implements Serializable {
	private int i;

	private String string;

	private byte[] byteArray;

	public SomeObject(int i, String string, byte[] byteArray) {
		this.i = i;
		this.string = string;
		this.byteArray = byteArray;
	}

	public String toString() {
		return "i = " + i + " string: " + string + " byteArray: "
				+ new String(byteArray);
	}
}
```

Client:

```
/**
 * 
 */
package de.tutorials;

import java.io.ObjectOutputStream;
import java.net.Socket;

/**
 * @author Tom
 */
public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		Socket socket = new Socket("localhost", 9876);

		ObjectOutputStream oos = new ObjectOutputStream(socket
				.getOutputStream());

		SomeObject so = new SomeObject(1789, "Foo", new byte[] { 21, 12, 111,
				12, 124, 14 });

		oos.writeObject(so);

		oos.flush();
		oos.close();
	}

}
```

Server:

```
/**
 * 
 */
package de.tutorials;

import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author Tom
 */
public class Server {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		ServerSocket serverSocket = new ServerSocket(9876);
		Socket socket = serverSocket.accept();

		ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
		SomeObject so = (SomeObject) ois.readObject();

		System.out.println(so);
		ois.close();

	}
}
```

HTH,

Gruß Tom


----------



## jma (26. April 2005)

Besten Dank
funkioniert wunderbar 
jma


----------



## codemaster (30. November 2009)

Hallo Thomas,

danke für das Beispiel.
Ich habe jedoch eine Frage dazu.

Es geht um ein Client/Server-Projekt.
Ich möchte gerne Objekte verschicken, die ich selbst per Klasse definiert habe.

Das funktioniert in deinem Beispiel ganz gut,
nur entwickle ich das Client-Programm getrennt vom Server-Programm in einem anderen Projekt.

Das scheint zu Problemen zu führen, da die Klasse (in deinem Fall SomeObject) es zwar in beiden Projekten gibt, aber wohl nicht als ein und die selbe aufgefasst wird.

dh. die: 

```
Exception in thread "main" java.lang.ClassNotFoundException: client.SomeObject
```


Wie kann ich dieses Objekt für beide Projekte nutzen? (damit sie serialisiert und deserialisiert werden können von 2 versch. Programmen)

Muss man diese dann extern einbinden?

Hoffe das geht so einfach 


Gruß


----------



## mccae (1. Dezember 2009)

codemaster hat gesagt.:


> Hallo Thomas,
> 
> danke für das Beispiel.
> Ich habe jedoch eine Frage dazu.
> ...



Huhu,

Ersteinmal möchte ich darauf hinweisen, dass dieser Thread knapp 4 Jahre alt ist...

Und nun zum Thema:
Deine Klasse muss beim Client und beim Server verfügbar sein (in der jar, oder wo auch immer).

In deinem Fall wird die Klasse SomeObject im Paket Client nicht gefunden. (Durchsucht wird (werden) der/die Classpath(s))

Die Klasse muss den selben Namen haben, und im selben Package sein wie die gesendete Klasse.

Weiters solltest der Klasse eine "serialVersionUID" hinzufügen (Eclipse fordert automatisch dazu auf, und zwar als "Warning").

Eine serialVersionUID wird anhand der Klasse generiert und ist einzigartig.
Sie dient dem Vergleich von serialisierten Objekten.

Sind zum Beispiel beide Klassen verfügbar, haben den selben Namen, jedoch zum Beispiel andere Attribute, gibt es Probleme.

Wenn du jedoch eine UID generiert hast, und der Server ein Objekt empfängt dessen UID nicht mit der der eigenen Klasse übereinstimmt, wird eine Exception geworfen.

So kannst du verhindern, dass fälschlicherweise eine inhaltlich ältere oder neuere Version der Klasse deserialisiert wird (wird sowieso ab irgendeinem Punkt geschehen)

Liebe Grüße,
Martin Conrad Caesar


----------



## Jellysheep (1. Dezember 2009)

Dankeschön, das Thema hat mich auch oft interessiert!


----------



## codemaster (5. Dezember 2009)

Danke dir!

Ja das mit dem Packetnamen ist mir auch gekommen und hat auch geklappt.

Und vielen Dank dass du mich noch auf diese UID aufmerksam gemacht hast


----------

