Questo accade perchè tu chiudi la ServerSocket da un metodo diverso da quello che effettua la accept.
Questo è lo scenario: hai una chiamata in corso al metodo accept() e tu, mentre (contemporaneamente) la chiamata è in corso, effettui una close(). Ovviamente la accept() va in errore.

Il metodo close() lo dovresti richiamare quando sei sicuro che non c'è nessuna accept() pendente.

Per assicurartene devi procedere in questo modo: impostare sulla ServerSocket un timeout. Significa che ogni tot millisecondi la accept termina (genera una eccezione che dovrai, ovviamente, controllare silenziosamente). In questo modo, controlli se è stata impostata a false la variabile che controlla il loop di ascolto. Se è stata impostata a false, effettui la close (tanto non rientrerà mai nella accept() ).


Ciao.