# Sendeproblem bei Server_Client



## Lange (27. Jun 2012)

Hallo,

ich versuche vom Server einen Text an den Client zu schicken. Dort soll der Benutzer seinen Namen oder quit eingeben. Wenn der Benutzer seinen Namen eingibt, soll es an den Server geschickt werden, der den Namn abspeichert und zur Bestätigung den Namen an den Client wieder zurück gibt. Mit quit soll der Client einfach geschlossen werden.

Wenn ich auf der Clientseite:

zuerst den InputStream aufbaue und das ganze Programm starte bekomme ich folgende Fehlermeldungen:

Server läuft!
IO-Error bei Client 1
java.net.SocketException: Connection reset
Protokoll fuer Client 1gestartet
	at java.net.SocketInputStream.read(Unknown Source)
	at java.ibjectInputStream$PeekInputStream.read(Unknown Source)
	at java.ibjectInputStream$PeekInputStream.readFully(Unknown Source)
	at java.ibjectInputStream$BlockDataInputStream.readShort(Unknown Source)
	at java.ibjectInputStream.readStreamHeader(Unknown Source)
	at java.ibjectInputStream.<init>(Unknown Source)
	at tests.Dienst.<init>(Dienst.java:26)
	at tests.MultiServer.main(MultiServer.java:15)
Exception in thread "Thread-0" java.lang.NullPointerException
	at tests.Dienst.run(Dienst.java:42)

Dann habe ich auf der ClientSeite zuerst den OutputStream geöffnet. Daraufhin läuft zwar das Programm. Aber der Server schickt dem Client irgendwie ständig den String, das er seinen Namen oder quit eingeben soll.

Nun meine Fragen:

Liegt der Fehler vll doch eher bei der ersten Variante wo ich bei Client zuerst den InputStream geöffnet habe? 

Oder muss man immer zuerst den OutputStream erzeugen, sodass der Fehler in der 2. Variante liegt?

Bin über jede Hilfe dankbar.

Hier noch der gesamte Programm Code:


```
package tests;

import java.io.*;
import java.net.*;

public class MultiServer {
	public static void main(String[] args) {
		try{
			int port = Integer.parseInt(args[0]);
			ServerSocket server = new ServerSocket(port);
			System.out.println("Server läuft!");
			while(true){
				Socket s = server.accept();
				new Dienst(s);
			}
		}
		catch(ArrayIndexOutOfBoundsException a){
			System.out.println("Aufruf: java TerminDienst<Port>");
		}
		catch(IOException e){
			e.printStackTrace();
		}
	}
}


package tests;

import java.io.*;
import java.net.*;

public class Dienst extends Thread {

	static int anzahl = 0;
	int nr = 0;
	Socket s;
	String name;
	ObjectInputStream vomClient;
	ObjectOutputStream zumClient;
	
	public Dienst(Socket s){
		try{
			this.s = s;
			nr = ++anzahl;
			vomClient = new ObjectInputStream(s.getInputStream());
			zumClient = new ObjectOutputStream(s.getOutputStream());
		}
		catch(IOException e){
			System.out.println("IO-Error bei Client " + nr);
			e.printStackTrace();
		}
		this.start();
	}
	
	public void run(){
		System.out.println("Protokoll fuer Client " + nr + "gestartet");
		String str = "Geben Sie Ihren Namen ein, oder beenden sie mit quit";		
		try{
			while(true){
				zumClient.writeObject(str);
				String getStr;
				getStr = (String) vomClient.readObject();
				if(getStr == null ||  getStr.equalsIgnoreCase("quit")){
					break;
				}
				else{
					name = getStr;
					zumClient.writeObject(name);
				}
			}
			s.close();
		}
		catch(IOException e){
			e.printStackTrace();
		}
		catch(ClassNotFoundException e){
			e.printStackTrace();
		}
	}	
}


package tests;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

public class MyClient {
	static void zeigeWasKommt(ObjectInputStream vomServer) throws IOException{
		
		try{
			Object o = vomServer.readObject();
			if (o instanceof String){
				while(o  != null)
				System.out.println(o);
			}
			else{
				System.out.println(o + " ist kein String!");
			}
			
		}
		catch(SocketTimeoutException sto){
		} 
		catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void main(String[] args){
		try {
			System.out.println("Client laeuft.Beenden mit Quit");
			Socket c = new Socket(args[0], Integer.parseInt(args[1]));
			c.setSoTimeout(500);
			ObjectOutputStream zumServer = new ObjectOutputStream(c.getOutputStream());
			ObjectInputStream vomServer = new ObjectInputStream(c.getInputStream());
			BufferedReader vonTastatur = new BufferedReader(new InputStreamReader(System.in));
			String zeile;
			
			do{
				zeigeWasKommt(vomServer);
				zeile = vonTastatur.readLine();
				zumServer.writeObject(zeile);
			}
			while(!zeile.equalsIgnoreCase("quit"));
			c.close();
		}
		catch(ArrayIndexOutOfBoundsException ae){
			System.out.println("Aufruf: java MyClient <Port-Nummer>");
		}
		catch(UnknownHostException u){
			System.out.println("Kein DNS-Eintrag " + args[0]);
		}
		catch(IOException e){
			e.printStackTrace();
		}
	}
}
```


----------



## SlaterB (27. Jun 2012)

einmal mehr gilt, häufiger Fehler, meine Spezialität im Forum hier  :
ObjectInputStream will leider gleich zu Beginn was lesen,
wenn beide Seiten ObjectInputStream aufmachen, warten sie auf Start-Token der Gegenseite, welches aber nicht kommen wird,
da ObjectOutputStream jeweils erst im Anschluss steht und nie drankommt wenn beide Seiten warten,
bzw. hier recht schnell Timeout

mit mindestens auf einer Seite erst ObjectOutputStream klappt es, besser auf beiden Seiten und immer erst den Output

-----

mit einer Schleife
> while(o  != null)
>                System.out.println(o);
musst du dich zu häufiger Ausgabe nicht wundern, wann soll das abbrechen, wer nebenher o verändern?


----------



## Lange (27. Jun 2012)

Hallo,

danke für die schnelle Antwort.

Habe nun auf beiden Seiten zuerst ObjectOutputStream erzeugt.

Nun funktioniert es auch.

Auf der Clientseite habe ich die Methode zeigeWasKommt noch ein wenig verändert.

String str;
Object o;
	try{
              while((o = vomServer.readObject()) != null){ 
	           if(o instanceof String){				
		       str = (String)o;					
		       System.out.println(str);
	           }	
              }
        }

Damit kann ich nun mehrere Strings vom Server gleich ausgeben.


----------

