# Objekte über das Netzwerk



## innocent (16. Jun 2010)

Hey!

Sitze an einer Programmieraufgabe für die Uni. Es geht um ein Kartenspiel. Um Fehlern direkt aus dem Weg zu gehen wollte ich direkt ein Objekt übertragen, welches die Karten enthält. Das funktionierte in meiner ersten Variante auch, jedoch sagten meine Gruppenleiter, dass es ein eher bescheidener Code ist (ich habe jedem Clienten einen Port zugeordnet).

Jetzt habe ich es neu geschrieben, es funktioniert nur leider nicht mehr. Vielleicht könnt ihr mir einen Tipp geben?

Ausschnitt Client:

```
socket = new Socket(Config.IP, Config.INITIAL_PORT);
oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject((SpielerDaten)this);
oos.flush();
oos.close();
```

Ausschnitt Server:

```
ois = new ObjectInputStream(client.getInputStream());
CL_Object clobject = null;
clobject = (CL_Object)ois.readObject();
```

An dieser Stelle gibt's immer einen Fehler.
Der Grund liegt wohl einfach darin, das ois.readObject() nicht darauf wartet, dass wirklich ein Objekt vorliegt. In meiner ersten Variante habe ich für jede Übertragung eine neue Verbindung aufgebaut, so dass ich immer das blockierende socket.accept() nutzen konnte.


Jemand eine Idee, wie ich den Code doch noch auf die Sprünge helfen kann?





Edit: Habe selbst gerade eine Idee gehabt: Wenn ich einen das serialisierte Objekt per readLine() empfange, habe ich eine blockierende Methode. Ich muesste also nur an die Serialisierung ein New-Line anhaengen und dann wieder entfernen? Ist das brauchbar?


----------



## homer65 (16. Jun 2010)

Client Code:

```
package client;
import java.net.*;
import java.io.*;
public class ServerRequest
{
	private static Socket con = null;
	private static OutputStream ou = null;
	private static ObjectOutputStream oo = null;
	private static InputStream in = null;
	private static ObjectInputStream oi = null;
	public static Object get(Object send)
	{
		Object received = null;
		try
		{
			con = new Socket(Parameter.host,Parameter.port);
			ou = con.getOutputStream();
			oo = new ObjectOutputStream(ou);
			oo.writeObject(send);
			oo.flush();
			in = con.getInputStream();
			oi = new ObjectInputStream(in);
			received = oi.readObject();
		}
		catch (Exception e)
		{
			Protokol.write("ServerRequest:Exception:" + e.toString());
			System.exit(12);
		}
		return received;
	}
}
```
Server Code:

```
package server;
import java.net.*;
import java.io.*;
public class MainThread extends Thread
{
	private int port = 0;
	ServerSocket sock = null;
	public MainThread(int port)
	{
		this.port = port;
	}
	public void run()
	{
		Protokol.write("MainThread:run:gestartet");
		try
		{
				sock = new ServerSocket(port);
				while (Global.runFlag)
				{
					try
					{
						Socket con = sock.accept();
						ArbeitsThread D = new ArbeitsThread(con);
						D.setDaemon(true);
						D.start();
					}
					catch (InterruptedIOException ie)
					{
						//Mache nichts
					}
				}
				sock.close();
		}
		catch (Exception e)
		{
			Protokol.write("MainThread:run:Exception:");
			Protokol.write(e.toString());
		}
		Global.runFlag = false;
		Protokol.write("MainThread:run:beendet");
	}
}
```


```
package server;
import java.io.*;
import java.net.*;
public class ArbeitsThread extends Thread
{
	private static int number = 0;
	public int myNumber = 0;
	public Socket con = null;
	public ArbeitsThread(Socket con)
	{
		this.con = con;
		InetAddress ia = con.getInetAddress();
		String client = ia.getHostAddress();
		myNumber = getNumber();
		Protokol.write("ArbeitsThread(" + myNumber + "): Created from " + client);
	}
	public void run()
	{
		Protokol.write("ArbeitsThread(" + myNumber + "):run:gestartet");
		InputStream in = null;
		OutputStream out = null;
		ObjectInputStream oi = null;
		ObjectOutputStream oo = null;
		try
		{
			in = con.getInputStream();
			oi = new ObjectInputStream(in);
			Object obj = oi.readObject();
			Verarbeitung V = new Verarbeitung(obj,this);
			Object obk = V.start();
			out = con.getOutputStream();
			oo = new ObjectOutputStream(out);
			oo.writeObject(obk);
			oo.flush();
		}
		catch (Exception e)
		{
			Protokol.write("ArbeitsThread(" + myNumber + "):Exception:" + e.toString());
		}
		Protokol.write("ArbeitsThread(" + myNumber + "):run:beendet");
	}
	public synchronized int getNumber()
	{
		number++;
		return number;
	}
}
```

Der Client schickt ein Object zum Server und erhält als Antwort ein anderes Object zurück.


----------



## Michael... (17. Jun 2010)

innocent hat gesagt.:


> An dieser Stelle gibt's immer einen Fehler.


Wie äussert er sich? Fehlermeldungen?


innocent hat gesagt.:


> Der Grund liegt wohl einfach darin, das ois.readObject() nicht darauf wartet, dass wirklich ein Objekt vorliegt.


Wie kommst Du drauf?


----------



## innocent (17. Jun 2010)

Hey!

Die Fehlermeldung:


> java.io.EOFException
> at java.ibjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2554)
> at java.ibjectInputStream.readObject0(ObjectInputStream.java:1297)
> at java.ibjectInputStream.readObject(ObjectInputStream.java:351)
> ...



Wie ich darauf komme? Ich habe nach einem Teil der Fehlermeldung das Internet durchforstet. Nachdem ich dann etwas gelesen habe, habe ich expliziet nach dem Funktionsaufruf gesucht und in den Java Doc gestoebert.
Als mir dann klar wurde, dass der Fehler bei deserialisieren des Objektes liegen muss habe ich den Quellcode dahingehend umgebaut, dass der Client nur eine Verbindung herstellt, ohne den Versuch ein Objekt zu senden. Selbe Fehlermeldung.

Mein Ergebniss: Es ist kein blockierendes Wort und die Fehlermeldung besagt, dass auf dem Stream zu dem Zeitpunkt kein Objekt vorliegt.



Habe jetzt eine neue Variante mit readLine() geschrieben, ich muss dann nur leider das Objekt per Hand serialisieren. Funktioniert, ist aber leider sehr unkomfortabel, vor allem wenn ich an spaetere Aenderungen denke. 


Naechste Idee:
Erst ein readLine() mit einem Codewort, danach dann die Abfrage nach dem Objekt. Duerfte funktionieren, oder? Ist das sinnvoll, oder soll ich lieber komplett auf readLine() setzen?


----------



## Michael... (17. Jun 2010)

innocent hat gesagt.:


> Mein Ergebniss: Es ist kein blockierendes Wort und die Fehlermeldung besagt, dass auf dem Stream zu dem Zeitpunkt kein Objekt vorliegt.


Die Fehlermeldung besagt, dass der Stream beendet ist und nichts mehr zum Lesen vorliegt.


----------



## innocent (18. Jun 2010)

Okay, danke für die Tipps. Habe es jetzt auf anderem Wege mit PrintWritern gelöst.


----------

