ObjectInputStream EOF

Kar

Mitglied
Hallo,

ich möchte mir einen kleinen Chat basteln aber bei der Übertragung fängt schon das Problem an.
Hier ersteinmal die Source-Dateien:

Server.java:
Java:
package chat.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class Server {
	private ServerSocket serverSocket;
	private ArrayList<Socket> clients;
	
	public Server(int port) {
		try {
			this.serverSocket = new ServerSocket(port);
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("Server wurde gestartet!");
		clients = new ArrayList<Socket>();
		ServerAcceptor acceptor = new ServerAcceptor(this);
		acceptor.start();
	}
	
	public ServerSocket getServerSocket() {
		return this.serverSocket;
	}
	
	public ArrayList<Socket> getClients() {
		return this.clients;
	}
	
	public static void main(String[] args) {
		new Server(1205);
	}
}

ServerAcceptor.java
Java:
package chat.server;

import java.io.IOException;
import java.net.Socket;

public class ServerAcceptor extends Thread {
	private Server server;
	
	public ServerAcceptor(Server server) {
		this.server = server;
	}
	
	@Override
	public void start() {
		super.start();
		System.out.println("ServerAcceptor wurde gestartet und wartet auf Anmeldungen!");
	}
	
	@Override
	public void run() {
		while(true) {
			try {
				Socket clientSocket = server.getServerSocket().accept();
				server.getClients().add(clientSocket);
				new ServerReader(clientSocket);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

ServerReader.java
Java:
package chat.server;

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

public class ServerReader extends Thread {
	private static int INST = 0;
	private Socket client;
	
	public ServerReader(Socket client) {
		INST++;
		this.client = client;
		this.start();
	}
	
	@Override
	public void start() {
		super.start();
		System.out.println("ServerReader: " + INST);
	}
	
	@Override
	public void run() {
		ServerActionController ctrl = ServerActionController.getInstance();
		ObjectInputStream ois = null;
		try {
			ois = new ObjectInputStream(client.getInputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
		while(true) {
			try {
				Object obj = ois.readObject();
				ctrl.doAction(client, obj);
			} catch(IOException e) {
				e.printStackTrace();
				//System.exit(0);
			} catch(ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
	}
}

ServerActionController.java
Java:
package chat.server;

import java.net.Socket;

import chat.objects.Message;

public final class ServerActionController {
	private static final ServerActionController INSTANCE = new ServerActionController();
	
	private ServerActionController() {}
	
	public static ServerActionController getInstance() {
		return INSTANCE;
	}
	
	public void doAction(Socket sender, Object obj) {
		if(obj instanceof Message) {
			Message msg = (Message) obj;
			System.out.println("-------------------");
			System.out.println(sender.getInetAddress().toString() + ":");
			System.out.println(msg.getMessage());
			System.out.println("-------------------");
		}
	}
}

Der wichtige Teil des Clients:
Java:
socket = new Socket("127.0.0.1", 1205);
oos = new ObjectOutputStream(socket.getOutputStream());
Message msg = new Message("Test");
oos.writeObject(msg);

Die Ausgabe sieht wie folgt aus:
Code:
Server wurde gestartet!
ServerAcceptor wurde gestartet und wartet auf Anmeldungen!
ServerReader: 1
-------------------
/127.0.0.1:
Test
-------------------
java.io.EOFException
	at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
	at java.io.ObjectInputStream.readObject0(Unknown Source)
	at java.io.ObjectInputStream.readObject(Unknown Source)
	at chat.server.ServerReader.run(ServerReader.java:37)
Nachdem ein Objekt übertragen wurde, wird in der ServerReader Klasse andauernd EOFExceptions geworfen. Blockiert readObject() nicht, bis etwas da ist, was gelesen werden kann? Wie kann ich das Werfen der Exceptions verhindern?

Ich bedanke mich für jede Antwort.

Gruß
 
S

SlaterB

Gast
da schreibst du soviel vom Server, aber nur 4 Zeilen vom Client?
grundsätzlich gilt die Regel dass die EOFException genau auch beim Ende des Streams kommt,
da der Server wahrscheinlich gerade nichts schlimmes macht wird der Client entweder den Socket geschlossen
oder irgendwie schlecht mit dem ObjectOutputStream umgegangen haben so dass der jedenfalls zu ist

> Blockiert readObject() nicht, bis etwas da ist, was gelesen werden kann?
falls übersehen: ein oder mehrere Objekte können durchaus erfolgreich gelesen sein worden,
die Schleife geht danach direkt wieder ins Lesen und dann kommt die Exception

mit den Ausgaben in ServerActionController allerdings vielleicht nicht zu übersehen
 

Kar

Mitglied
Danke für deine Antwort.
Der Client besteht bisher nur aus einer kleinen Testklasse, in der eine Verbindung zum Server aufgebaut, ein Objekt gesendet und anschließend alles geschlossen wird.

Java:
package chat.client;

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

import chat.objects.Message;


public class Client {

	public Client() {
		Socket socket = null;
		ObjectOutputStream oos = null;
		try {
			socket = new Socket("127.0.0.1", 1205);
			oos = new ObjectOutputStream(socket.getOutputStream());
			Message msg = new Message("Test");
			oos.writeObject(msg);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				socket.close();
				oos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		new Client();
	}
}

Liegt es also daran, dass ich clientseitig die Verbindung einfach abbreche, ohne den Server vorher darüber zu informieren?
 
S

SlaterB

Gast
der Client muss nicht unbedingt informieren, ohne Timeout-Konfiguration wird es beim Server eh schwer, das read() abzubrechen,
siehe die Exception hier nicht als Problem sondern als Steuerung an und reagiere darauf entsprechend,
im Moment wird weiter gelesen, Endlosschleife, bei EOFException oder vielleicht bei allen ist zumindest Ende der while-true-Schleife zu überlegen,

die erste Test-Nachricht wird auch vor der Exception erfolgreich übertragen, habe es gerade getestet,

edit:
ein Ende-Objekt zu senden ist natürlich relativ elegant,
dann kann ganz normal aus der Schleife gesprungen werden
 
H

hansmaulwurfsim

Gast
Habe gerade durch Google diesen Thread gefunden und hätte ziemlich genau dazu noch eine Frage:

Wenn man bei einem DataInputStream readUTF() verwendet, bleibt mein Thread ja jedes Mal stehen und wartet, bis was kommt -> kein busy waiting

Genau das will ich jetzt auch mit einem ObjectInputStream erreichen. Da ich nicht weiß, wann genau ein Objekt kommt, soll der Thread einfach hören und wenn ein Objekt kommt, das Ganze behandeln.
Da readObject() aber anscheinend null oder eof zurückgibt, falls kein Objekt ankommt stehe ich vor einem Problem.
Natürlich könnte ich das abfangen und die Schleife neu starten, dann hätte ich aber busy waiting und das ist ja wohl nicht Sinn der Sache.

Hat jemand eine Idee, wie man das lösen könnte?

Danke
 
S

SlaterB

Gast
Busy waiting funktioniert genauso,
null wird höchstens dann gelesen wenn auch null drinsteht, EOF kommt eben beim Ende des Streams,
solange der Stream offen ist gibt es auch keine Probleme, anderenfalls versagt jeder Stream auf gleiche Weise
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D new ObjectInputStream(socket.getInputStream()); Netzwerkprogrammierung 15
G ObjectOutputStream und ObjectInputStream machen Ärger Netzwerkprogrammierung 17
F ObjectInputStream.readObject() mehrfach aufrufen Netzwerkprogrammierung 2
J ObjectInputStream im Netzwerk Netzwerkprogrammierung 8
G ObjectInputStream hängt ganzes Programm auf... Netzwerkprogrammierung 7
X ObjectInputStream StringCorruptedException Netzwerkprogrammierung 3
V StreamCorruptedException bei ObjectInputStream und ObjectOStream Netzwerkprogrammierung 5
S FileInputStream und ObjectInputStream Netzwerkprogrammierung 18
C Socket ObjectInputStream liest nur Objekte der jeweiligen Programminstanz Netzwerkprogrammierung 5
M InputStream and ObjectInputStream zur gleichen Zeit Netzwerkprogrammierung 11
J Socket ObjectInputStream prüfen Netzwerkprogrammierung 8
N Socket neue Referenz auf ObjectInputStream Netzwerkprogrammierung 13
E Rausfinden ob noch Objecte in ObjectInputStream Netzwerkprogrammierung 5
Y Problem mit ObjectInputStream beim lesen vom Socket Netzwerkprogrammierung 10
C komisches Problem / ObjectInputStream erstellt sich nicht Netzwerkprogrammierung 5
K ObjectInputStream mit CypherInputStream hängt Netzwerkprogrammierung 7
G Datei über ObjectInputStream versenden Netzwerkprogrammierung 8
R ObjectOutput- / ObjectInputStream Exception? Netzwerkprogrammierung 2
E ObjectInputStream/ObjectOutputStream nicht erzeugbar Netzwerkprogrammierung 2
T Problem mit ObjectInputStream Netzwerkprogrammierung 2
C Kollision von ObjectInputStream und BufferedReader ? Netzwerkprogrammierung 6
G ObjectInputStream gebuffert? Netzwerkprogrammierung 3

Ähnliche Java Themen


Oben