# Client-Server Problem



## Kizz (3. Dez 2007)

Hi,

Arbeite mich grad in Sockets, Streams etc ein wenig ein und wollte deshalb einen Chat programmieren.
Als Grundgerüst habe ich mir die Struktur des Chats aus der FAQ abgeschaut.
Momentan siehts so aus, dass der Server zwar Sachen empfängt und verarbeitet, allerdings das Senden
an den Client funktioniert noch nicht so 100%ig. Komischerweise hats schonmal funktioniert, aber als
ich es kurz drauf gleich nochmal probieren wollte (ohne was am Code verändert zu haben), klappte es
plötzlich nicht mehr oO

Ich versuch mal, das wichtigste zu posten, evtl hat jemand ne Ahnung und kann mir Tips geben:

Zuerst die Funktion, die meinen Client startet:
Evtl könnte auch hier schon ein Fehler sein, ich hab nämlich noch nicht so genau überrissen, was
die while-Schleife macht. Die übertragene Message hol ich mir aus ClientBody, da es mir schon passiert
ist, dass ich die Message schon vorher ausgelesen hab und die Übertragung dann im ClientBody null war.

```
void startClient() throws Exception{
		BufferedReader in;
		BufferedWriter out;
		String msg;
		s=new Socket(ip, port);
		in=new BufferedReader(new InputStreamReader(s.getInputStream()));
		out=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		ClientBody cb=new ClientBody(s,this);
		cb.start();
		while(!(cb.getMsg().trim()).equals("exit")){}
		in.close();
		out.close();
	}
```

Hier die erste Funktion, die etwas an den Server sendet:

```
void checkDoubleName(String name){
		try{
			BufferedWriter out=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
			this.name=name;
			out.write("checkdouble"+name);
			out.newLine();
			out.flush();
			out.close();
		}catch(Exception e){}
	}
```

Hier der ClientBody: (nur die Funktion run, damits nicht so lang wird)

```
public void run(){
            BufferedReader in;
	    BufferedWriter out;
	   
	    try{
		   in=new BufferedReader(new InputStreamReader(s.getInputStream()));
		   out=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		  
	       while ((msg=in.readLine())!= null){
	    	 
	    	   //result of checking double names
	    	   if(msg.length()>=11 && msg.substring(0,11).equals("checkdouble")){
	    		   if(msg.substring(11,msg.length()).equals("true")){
	    			   c.login.setVisible(false);
	    			   c.newUser(c.name);
	    			   UserView uv=new UserView();
	    			   uv.setVisible(true);
	    		   }else{
	    			   c.doubleName();
	    		   }
	    	   }
	       }   
	    }catch (IOException io) {}   
    }
```

Hier die run-Funktion des ServerBody:

```
public void run(){

	    String msg;
	    
	    try{
			BufferedReader in=new BufferedReader(new InputStreamReader(cs.getInputStream()));
	        msg=in.readLine();
			System.out.println(msg);
	        
			BufferedWriter out=new BufferedWriter(new OutputStreamWriter(cs.getOutputStream()));
	      
	        //checking for double user names 
	        if(msg.length()>=11 && msg.substring(0,11).equals("checkdouble")){
	    	    if(server.checkDouble(msg.substring(11,msg.length()))){
	    			System.out.println(msg);
	    	    	out.write("checkdoubletrue");
	    	    	out.newLine();
	    	    	out.flush();
	    	    }else{
	    		    out.write("checkdoublefalse");
	    		    out.newLine();
	    		    out.flush();
	    	    }
	        }
	      
	        //adding new user
	        if(msg.length()>=7 && msg.substring(0,7).equals("newuser")){
	    	    server.addUser(msg.substring(7,msg.length()),this);
	        }
	      	      
	        in.close();
	        out.close();
	    }catch(IOException io){}
    }
```

Kurz noch zum Ablauf:
Meine Frame-Klasse startet den Client und ruft anschließend eine Funktion auf, die dem Server
einen String bestehend aus dem Wort "checkdouble" und einem Namen sendet.
Der Server überprüft dann zuerst, welchen "Befehl" er erhalten hat und anschließend ob der Name
schon in der Clientliste vorhanden ist. Wenn der Name verfügbar ist, soll "checkdoubletrue" zurückgesendet
werden.
Im Client soll dann bei Eingang eines Strings zuerst wieder überprüft werden, welcher "Befehl" es ist und dann,
sofern es "checkdouble" und "true" ist, das eigentliche Fenster verschwinden lassen, dann ein neues Fenster öffnen
und einen Befehl an den Server schicken, dass der neue User in der Clientliste angelegt wird.

Hauptprobleme sind nun folgende:
-meistens kommt der String vom Server zum Client nicht an und ich hab keine Ahnung wieso. Sprich, es wird mir
vom Server noch ausgegeben, welchen String er erhalten hat und dann passiert einfach garnichts mehr.
-in dem einen Fall, wo es tatsächlich funktioniert hat, verschwand das Login-Fenster, das neue Fenster wurde
angezeigt...aber es wurde kein Befehl an den Server gesendet, dass der neue User angelegt wird (ich lass mir
in der Konsole immer anzeigen, welche Strings beim Server eingehen)

Bin deswegen grad ziemlich ratlos.
Würd mich über Hilfe freuen.

Gruß, Kizz


P.S.: Kurze Frage zu Streams allgemein: Wenn ich meine Programme ausserordentlich beende, werden
dann die Streams trotzdem geschlossen? Oder kann da was im Speicher hängenbleiben, dass mir beim
nächstenmal dazwischenfunken könnte?

P.P.S: Wenn ihr noch mehr Codestücke wollt/braucht, einfach Bescheid sagen.


----------



## madboy (3. Dez 2007)

Ich muss zugeben dass ich mir nicht alles durchgelesen habe und daher nicht sagen kann "daran hängts" aber was mir aufgefallen ist:
Gaaaanz schlecht wenn was schief läuft:

```
}catch(Exception e){}
```
Ersetze am besten alle catch(...){} durch

```
}catch(...){e.printStackTrace();}
```

Dann bekommst du nämlich im Fehlerfall eine (recht detaillierte) Ausgabe und weißt somit, wo und was nicht klappt.


----------



## Kizz (4. Dez 2007)

Ok, danke für den Tip.


----------

