# bring den Server nicht zum "lauschen"



## Gayson (28. Jun 2004)

Hallo!

Folgender Code steht bei meinem Chatserver:


```
Thread thread = new Thread(){
			public void run(){
					try {
						while(true) {
								ss = new ServerSocket(1100);
								s = ss.accept();
								aus = new PrintWriter(s.getOutputStream(),true);
								ein = new BufferedReader(new InputStreamReader(s.getInputStream()));
								eingang = ein.readLine();
								// in Chatfenster schreiben
								while (!eingang.equals("bye")) {
									appendText(eingang, "0"); // Text ans Chatfenster dranhängen
									eingang="";
									eingang = ein.readLine();
								}
								Thread thr = new Thread();
						}
					} catch (IOException e){
						e.printStackTrace();
					}
			}
		};
		thread.start();
```

Wenn ich z.B. diese Reihenfolge ausführe

1. Server starten
2. Client starten
3. Nachrichten schreiben ... klappt
4. Client schließen
5. Client starten

kommen danach weder beim Server noch beim Client Nachrichten an...

Woran liegt das?


----------



## L-ectron-X (28. Jun 2004)

Die Verbindung wird scheinbar nirgens geschlossen und der Server kommt nicht mehr zum Lauschen.


----------



## Dante (28. Jun 2004)

hm, chaotisch.

Warum machst du nicht einen thread für den serversocket und machst dann für jede verbindung einen weiteren Thread auf, der sich um den socket kümmert.

imho springt der server bei dir auch mit einer exception raus, wenn der client weg ist?!

wozu ist das gut? "Thread thr = new Thread();"

das hier: "eingang="";" ist auch unnötig, readLine blockeirt ja solange bis entweder nen zeilenumbruch kommt oder der verbindungspartner weg ist (dann kommt entweder ne exception oder null zurück, bin mir da grad nicht sicher)


----------



## L-ectron-X (28. Jun 2004)

Alles was nach accept() kommt, sollte besser in einen eigenen Thread, weil der Server nicht mehr lauschen kann.
Die while-Schleife sollte etwa so aussehen:

```
while(true) {
  Socket client = socket.accept();
  //hier dann den Arbeits-Thread starten
}
```

Edit: Ups. Das war 'n Fehlklick bei mir. :roll:


----------



## Gayson (29. Jun 2004)

Hallo!
Habe mir alles, was ihr gesagt habt, zu Herzen genommen, und auch noch ein bisschen im Forum gestöbert.

Das ist dabei rausgekommen:


```
try {
			ss = new ServerSocket(1100);
			while(true) {
				s = ss.accept();
				ServerThread t = new ServerThread(s);
				t.start();
			}
		} catch(IOException e){}

[...]

	public class ServerThread extends Thread {
		private Socket s;
		public ServerThread(Socket s) {
			this.s = s;
		}

		public void run() {
			try{
				BufferedReader ein = new BufferedReader(new InputStreamReader(s.getInputStream()));
				eingang = ein.readLine();
				BufferedWriter aus = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
				while (!eingang.equals("bye")) {
					appendText(eingang, "0");
					eingang="";
					eingang = ein.readLine();
				}
				aus.close();
				ein.close();
			} catch (IOException e) {}
		}
```

Folgendes z.B. geht jetzt
1. Server starten
2. Client starten
3. Nachricht von Client an Server ... klappt
4. Client schließen
5. Client starten
6. Nachricht von Client an Server ... klappt

Aber jede Nachricht von Server an Client klappt jetzt nicht mehr...

Woran könnts liegen?


----------



## Gayson (29. Jun 2004)

Hab mal selbst versucht, es zu schaffen, blieb leider erfolgslos....
Keiner eine Idee?


----------



## meez (29. Jun 2004)

Du schreibst ja im Server-Thread auch keine Nachricht an den Client...
Du initialisierst nur den BufferedWriter, wartest bis der Client alles gesendet hat was er will, und schliesst den Output wieder....


----------



## Gayson (29. Jun 2004)

Welche Änderungen soll ich denn im Code vornehmen?

Habe mal das 


```
aus.close();
            ein.close();
```

rausgenommen, ohne klappts auch nicht. 

Wie schaff ich es denn, dass der BufferedReader solang offen bleibt, wie auch der Client online ist?


----------



## meez (29. Jun 2004)

Du musst auch die Rückmeldungen, als out.write(...) im Thread erledigen....


----------



## Gayson (30. Jun 2004)

Hm, ich schaffs immer noch nicht.

Obwohl ich ein out.write("Hi") vor die while()-Schleife gesetzt habe, kommt kein "Hi" am Client an.

Hier mal der gesamte relevante Code:


```
public class Chatserver extends JFrame implements ActionListener, KeyListener, WindowListener {
    public Chatserver() {

		try {
			ss = new ServerSocket(1100);
			while(true) {
				s = ss.accept();
				ServerThread t = new ServerThread(s);
				t.start();
			}
		} catch(IOException e){}
    }


	// Serverthread, wartet auf neue Verbindungen
	public class ServerThread extends Thread {
		private Socket s;
		public ServerThread(Socket s) {
			this.s = s;
		}

		public void run() {
			try{
				BufferedReader ein = new BufferedReader(new InputStreamReader(s.getInputStream()));
				eingang = ein.readLine();
				PrintWriter aus = new PrintWriter(s.getOutputStream(),true);
				aus.write("Hi");
				while (!eingang.equals("bye")) {
					appendText(eingang, "0");
					eingang="";
					eingang = ein.readLine();
				}
			} catch (IOException e) {}
		}
	}


	// Text versenden
	public void sendText(String texttosend) {
		try {
			String text="<font size=\"3\" face=\"Courier\">[b]" + username + ": [/b]" + texttosend + "</font>";
			aus.println(text);
		} catch (NullPointerException e){
			JOptionPane.showMessageDialog(null, "Es ist kein anderer User online", "Hinweis", JOptionPane.ERROR_MESSAGE);
		}
	}


	// Keyevents
	public void keyPressed (KeyEvent evt) {
    }
	public void keyReleased (KeyEvent evt) {
		int  x = evt.getKeyCode();
		if (x == KeyEvent.VK_ENTER) {
			appendText(eingabe.getText(), "1");
			sendText(eingabe.getText());
			eingabe.setText("");
		}
		repaint();
```


----------



## Dante (30. Jun 2004)

Relevant wäre hier der Code des Clients.


----------



## Gayson (30. Jun 2004)

Gesagt, getan :


```
Thread thread = new Thread(){
			public void run(){
				try {
					s = new Socket("192.168.0.10",1100);
					aus = new PrintWriter(s.getOutputStream(),true);
					ein = new BufferedReader(new InputStreamReader(s.getInputStream()));
					eingang = ein.readLine();
					// in Chatfenster schreiben
					while (!eingang.equals("bye")) {
						appendText2(eingang);
						eingang="";
						eingang = ein.readLine();
					}
					ein.close();
					aus.close();
					s.close();
				} catch (IOException e){
					e.printStackTrace();
				}
			}
		};
		thread.start();
```

Wie gesagt, Nachrichten vom Client zu Server gehen, bei Nachrichten vom Serber zu Client kommt die Fehlermeldung "Es ist kein anderer User online", also eine NullPointerException


----------



## Gayson (30. Jun 2004)

Es muss doch irgendwo ein Fehler sein??


----------



## Dante (30. Jun 2004)

Den Fehler hab ich auch mal gemacht 

Der Client liest eine Zeile, das heisst der Reader blockiert solange bis er einen Zeilenumbruch liest.

Problem ist: Du schickst keinen (aus.write("Hi"), daher wartet der Server bis er blöde wird (das kann bei einem Computer recht lange dauern  )

Einfach per \n oder der Methode newLine() einen Zeilenumbruch senden und es sollte weiter gehen.


----------



## meez (30. Jun 2004)

oder schöner aus.flush(); am ende...


----------



## Dante (30. Jun 2004)

nö, was hat den flush mit dem schicken eines zeilenumbruchs zu tun? flush leert nur den cache, das ist _nicht_ gleichbedeutend mit dem ende einer Zeile.

Der Zeilenumbruch ist ja auch abhängig vom verwendeten Encoding, ein Zeilenumbruch in UTF-16 sieht ja ganz anders aus als in US-ASCII (was meist die Standardeinstellung der VM ist, also benutzt wird, wenn kein Encoding spezifiziert wird).

Geflushed werden sollte hier aber natürlich auch noch


----------

