# Socket.Accept() unterbrechen?



## JayJay (2. Okt 2007)

Hallo Leute, und zwar hab folgenden Server-Aufbau:

1. Nimmt Clients an und erstellt damit einen neuen Thread
2. Einige Client-Threads (1..5)

Jetzt will ich ein Shutdown mechanismus einbauen. D.h.

> Wenn ein Client Shutdown durchführt, warten bis alle clients disconnected sind.


Mein Problem liegt darin, dass zb. 2 Client connected sind (schön und gut), der server ist gerade auf listening .... (wartet auf einen neuen Client).

# 1. Client initiiert shutdown, und disconnected
   * Server speichert shutdown 
# 2. der andere Client macht was anderes und disconnected

Der Server ist aber gerade im listening modus. Dies müsste ich irgendwie von extern von einem Thread beenden? Geht das irgendwie?

Mit Close würde ich alle clients raushauen, will aber warten bis alle disconnected sind?


Also Frage:
----------------------
Wie kann ich die Funktion socket.accept() unterbrechen? oder einen Timer einabauen, um eine Variable zu prüfen. Würde mich über ein paar Ideen Freuen!!  :toll:


----------



## tuxedo (2. Okt 2007)

Hmm... Ja, da ist was dran. Bisher hab ich meine Server immer mit CTRL+C abgebrochen. 

Aber mir fällt da gerade was ein, was vielleicht nicht unbedingt die beste Lösung ist:

Du machst nach dem accept eine abfrage auf "shutdown initiated?". Wenn ein Shutdown gestartet wurde klappt das accept() zwar noch, tut aber nix mehr sinnvolles, weil ja ein shutdown gestartet wurde. So verhinderst du erstmal dass sich trotzdem neue clients einloggen.

So. Wenn sich dann doch einer versucht einzuloggen kannst du aus der "while" schleife die mit accept() bisher blockiert hat "ausbrechen". 

Wenn keiner mehr connected blockiert accept() ja weiterhin. Du könntest dann den rest der Anwendung sauber runterfahren, alles abspeichern etc. und dann ein System.exit(0); machen. Dann ist auch alles beendet. 

- Alex


----------



## JayJay (2. Okt 2007)

Das ist richtig. Nur, wenn kein Client sich mehr connected, wars damit


----------



## Niki (2. Okt 2007)

Du kannst beim ServerSocket ein timeout definieren.:
setSoTimeout
Bau einfach eine Schleife mit einem flag drumherum. Solange das flag auf true ist lauscht der ServerSocket weiter. Ansonsten schließt du die anderen Sockets bzw. machst andere Aufräumungsarbeiten. Der Client der den Server herunterfahren möchte setzt das flag auf false.
Das könnte so aussehen (nicht ausprobiert)

```
private boolean _continue = true;


public void run(){
  serverSocket = new ServerSocket(port);
  serverSocket.setSoTimeout(500); //halbe Sekunde sollte ja reichen
  while(_continue){
    try{
      Socket s = serverSocket.accept();
      new Thread(new SocketWorker(s)).start();
    }catch(SocketTimeoutException ignore){
    }
  }
  //Server wurde geschlossen, Aufräumungsarbeiten durchführen
}

public void stop(){
  _continue = false;
}
```


----------



## JayJay (2. Okt 2007)

PS: Momentan läuft das genau so bei mir


----------



## JayJay (2. Okt 2007)

@Niki: super idee. besten dank für deine schnelle hilfe. Natürlich auch danke an alex0801!


----------



## JayJay (2. Okt 2007)

Okay, funktioniert alles wirklich sauber und ohne Probleme vielen Dank!!


----------



## tuxedo (2. Okt 2007)

An das Timeout hatte ich gar nicht mehr gedacht (verwende das so selten). Natürlich ist das wohl die sauberste Lösung.

- Alex


----------

