# ObjectInputStream.readObject() mehrfach aufrufen



## Finn10111 (7. Jun 2012)

Ich hoffe der Titel ist nicht zu schlimm gewählt. Mein Ziel ist es, eine Anwendung zu schreiben, die eine Client- und eine Server-Klasse enthält. Ein Server soll erstellt werden, ein Client soll verbinden, der Client soll eine Nachricht schicken, dann noch eine. Die Verbindung soll in der Zwischenzeit gehalten werden. An meiner Start.java wird hoffentlich klar, was ich vor habe:

Start.java

```
public class Start {
	public static void main(String[] args)  {
		
		int port = 10058;
		
		Server aServer = new Server(port);
		aServer.startListening();

		Client aClient = new Client("localhost", port);

		aClient.connect();
		aClient.send("TEST1");
		aClient.send("TEST2");
	
		aClient.close();
		
		aServer.stopListening();
	}
}
```

Server.java

```
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server implements Runnable {
    private ServerSocket aServerSocket = null;
    private Socket aSocket = null;
    private int port;
    private Boolean close = false;
	private ObjectOutputStream oos = null;
	private ObjectInputStream ois = null;
    
    public Server(int port)
    {
    	this.port = port;
    }
    
    public void startListening()
    {
    	try {
			aServerSocket = new ServerSocket(port);
			Thread thread = new Thread(this);
			thread.start();
			System.out.println("Server Socket erstellt");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
	@Override
	public void run() {
		// TODO Auto-generated method stub
    	while(!close)
    	{
    		try {
				aSocket = aServerSocket.accept();
				receive();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				//e.printStackTrace();
				System.out.println("Socket geschlossen.");
			}
    	}
	}
    
    
    public void receive()
    {
		try {
			ois = new ObjectInputStream(aSocket.getInputStream());
			String message = (String) ois.readObject();
			oos = new ObjectOutputStream(aSocket.getOutputStream());
			oos.writeObject("REPLY " + message);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
    }

	public void stopListening()
	{
        try {
        	close = true;
        
	        if (aServerSocket != null) {
				aServerSocket.close();
			}
			System.out.println("Server closed connection.");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
```


Client.java

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

public class Client {

	private Socket aSocket;
	private String server;
	private int port;
	
	private ObjectOutputStream oos = null;
	private ObjectInputStream ois = null;

	public Client(String server, int port)
	{
		this.server = server;
		this.port = port;
	}

	public void connect()
	{
	    try 
	    {
	    	aSocket = new Socket(server, port);
	    	aSocket.setKeepAlive(true);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	
	public void send(String message)
	{
		try {
			if (oos == null) {
				oos = new ObjectOutputStream(aSocket.getOutputStream());
			}
			oos.writeObject(message);
			if (ois == null) {
				ois = new ObjectInputStream(aSocket.getInputStream());
			}
			String receivedMessage = (String) ois.readObject();
			System.out.println("Response from Server: " + receivedMessage);
	
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			// oid.readObject;
			e.printStackTrace();
		}
	}
	
	public void close()
	{
        try {
			ois.close();
			oos.close();
	        aSocket.close();
	        System.out.println("Client closed connection.");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
```


Ich habe nun 2 Fragen:

1. Wie gehe ich genau mit den Streams um? Wenn ich 2 mal einen Text senden möchte, muss ich jedes mal "oos = new ObjectOutputStream(aSocket.getOutputStream());" aufrufen oder brauche ich die "if ( oos == null)" Bedingung?
2. Die zweite Nachricht kommt nicht beim Server an, da das receive() des Servers ja nur einmal nach dem "aSocket = aServerSocket.accept();" aufgerufen wird. Wie bringe ich den Server dazu, auch mehrere Nachrichten empfangen zu können? Wenn ich den Inhalt von receive() testweise in eine while(true) Schleife packe, bekomme ich haufenweise Exceptions an den Kopf geworfen. 

Ich bin anscheinend ein wenig auf dem falschen Dampfer, ich hoffe ihr könnt mir einige Ratschläge geben, wie ich das hinbekomme. 

Danke


----------



## SlaterB (7. Jun 2012)

1. Streams immer nur einmal drauflegen und merken, das ist wichtig
2. mit den Exceptions ist zu leben, falls nicht der Client netter agiert, etwa vorher die Anzahl der Objekte sendet,
so dass nur genau so oft abgefragt wird,
oder generell nur ein Objekt gesendet wird, etwa ein Liste, mit mehreren Nachrichten darin,

das muss nicht der Fall sein, dann die while(true)-Schleife und leider mag ObjectInputStream am Ende eine Exception,
nicht leicht zu vermeiden, ist ok, mit try/catch behandeln, als Ende ansehen


----------



## FArt (11. Jun 2012)

Tipp:
* Streams immer in finally-Blöcken schließen
* Wenn du nicht nur "spielen" möchtest, verwende für die Kommunikation eine API wie z.B. Netty oder Apache MINA. Die kümmern sich um viele technische Sachen unter drunter (Pooling, Verbindungsabbrückhe usw.) und du kannst dich um deine Applikation kümmern. 
* Wenn du in Java mit ObjectStreams arbeitest musst du evtl. regelmäßig reset verwenden, um einen OutOfMemory im Cache des Streams zu vermeiden. Auch das spricht wieder für den zweiten Punkt ;-)


----------

