# ServerSocket.accept() unterbrechen



## HazlNut (16. Jan 2014)

Moinsen!

Hab gerade mal ne halbe stunde verbracht um das Forum zu durchsuchen, aber leider nichts was mich betrifft gefunden...Na dann mal nen neuen Thread öffnen

Also mein Problem ist folgendes:

Soll einen ganz normalen Multichat erstellen der Nachrichten von Clients an alle verteilt. Aufgabe ist auch, dass sobald man in der GUI des Servers auf Stop drückt, alles fein säuberlich geschlossen wird.
In meiner GUI fängt das dann so an:


```
public void actionPerformed(ActionEvent e) {
		String command = e.getActionCommand();

		if (command.equals("start")) {
			start = new Thread(new ServerChatStarter());
			start.start();
		} else if (command.equals("stop")) {
			sc.stop();
			System.out.println("acceptClient = false");
		} else if (command.equals("send")) {
			
		}
	}
```
Im Serverchat steht dann folgendes:


```
public void stop(){
		acceptClient = false;
	}
	
	public void start(){
		try {
			chatTeilnehmer = new TeilnehmerListe();
			messages.setText("Server wird gestarted.\nPort wird geoeffnet\n");
			serverSocket = new ServerSocket(port);
			while(acceptClient){
				connect = new Thread(new ConnectionHandler(serverSocket.accept(), messages));
				messages.append("Client accepted\n");
				connect.start();
				messages.append("Connectionhandler gestartet.\n");
			}
			System.out.println("Interrupt wird gesetzt.");
			connect.interrupt();
		} catch (IOException e) {
			messages.append("Port konnte nicht geoeffnet werden\n");
		}
	}
```

Problem ist dabei, accept() ist ja blockierend und es passiert einfach nichts ;(
Habe es schon mit einem setSoTimeOut versucht (evtl aber falsch da es nicht geklappt hat :applaus: )
Hoffe es gibt diese Frage nicht schonmal und bedanke mich schonmal für Antworten.

LG


----------



## Sen-Mithrarin (17. Jan 2014)

ähm ... da sind aber mal gleich mehrere fehler drin versteckt

1) du hast einen Thread / Runnable und diese enthält start() und stop() ! vorsicht : ungewolltest override !
nutze lieber eindeutige namen startServer() und stopServer() !

2) beim starten hast du : start = new Thread(new ServerChatStarter()); start.start(); ... greifst dann beim stoppen aber auf "sc" zu ...
zwei referenzen auf EIN objekt ? oder mehrere objekte ?

3) ServerSocket.accept() direkt im konstruktor call ? ouchn ... da hast du dann gleich mehrere halb-offene sachen
packe das accept() in eine extra zeile für einen sauberen aufruf



4) ServerSocket.accept() kann man nicht "sauber" beenden
entweder muss man auf eine verbindung warten, oder den ServerSocket gewaltsam schließen was in eine Exception läuft


----------



## turtle (18. Jan 2014)

> 4) ServerSocket.accept() kann man nicht "sauber" beenden



APi-Doc: [JAPI]ServerSocket[/JAPI]

Da steht doch eindeutig zu accept

```
SocketTimeoutException - if a timeout was previously set with setSoTimeout and the timeout has been reached.
```

Also ist das Reagieren auf eine SocketTimeoutException eine saubere Angelegenheit..


----------



## HazlNut (18. Jan 2014)

Jaa ich bin echt nich der beste würde ich ma sagen 
Tu aber mein möglichst bestes 



> 1) du hast einen Thread / Runnable und diese enthält start() und stop() ! vorsicht : ungewolltest override !
> nutze lieber eindeutige namen startServer() und stopServer() !



Das hab ich inzwischen beseitigt 



> 2) beim starten hast du : start = new Thread(new ServerChatStarter()); start.start(); ... greifst dann beim stoppen aber auf "sc" zu ...
> zwei referenzen auf EIN objekt ? oder mehrere objekte ?



Also dieser ServerChatStarter macht eigentlich nur folgendes:

```
public class ServerChatStarter implements Runnable{

		@Override
		public void run() {
			sc = new ServerChat(Integer.parseInt(serverPort.getText()), messages);
			sc.startServer();			
		}		
	}
```

Meine GUI is komischerweise eingefroren, wenn ich direkt beim startbutton new ServerChat gesagt hab.
Also im Endeffekt geht es darum beim drücken von stop auf sc zuzugreifen.



> 3) ServerSocket.accept() direkt im konstruktor call ? ouchn ... da hast du dann gleich mehrere halb-offene sachen
> packe das accept() in eine extra zeile für einen sauberen aufruf



Hab ich auch beseitigt und sieht jetz so aus:

```
while(acceptClient){
				Socket socket = serverSocket.accept();
				connect = new ConnectionHandler(socket, messages);
				messages.append("Client accepted\n");
				connect.start();
				messages.append("Connectionhandler gestartet.\n");
			}
```



> 4) ServerSocket.accept() kann man nicht "sauber" beenden
> entweder muss man auf eine verbindung warten, oder den ServerSocket gewaltsam schließen was in eine Exception läuft



Hab das ganze jetzt einfach mal so geschrieben:

```
public void stopServer(){
                for (Teilnehmer target : TeilnehmerListe.chatTeilnehmer) {
			target.serverConnectionHandler.sendToClient("disconnect:ok");
		}
		for (Teilnehmer target : TeilnehmerListe.chatTeilnehmer) {
			target.serverConnectionHandler.interrupt();
		}
		
		try {
			serverSocket.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
```
Die erste for-each-Schleife sendet disconnectk und sobald die clients das empfangen schließen sie ihre sockets und in und outputs
und die zweite soll dann halt die connectionhandler interrupten. Kann man das einfach so machen oder is da noch ein fehler drin?


Vielen dank aber schonmal für die Antworten!:toll:


----------

