Dans mon thread principal, j'ai une while(listening)
boucle qui appelle accept()
mon objet ServerSocket, puis démarre un nouveau thread client et l'ajoute à une collection lorsqu'un nouveau client est accepté.
J'ai également un thread d'administration que je souhaite utiliser pour émettre des commandes, telles que `` exit '', ce qui entraînera l'arrêt de tous les threads clients, l'arrêt d'eux-mêmes et l'arrêt du thread principal, en activant l'écoute sur false.
Cependant, l' accept()
appel dans la while(listening)
boucle se bloque et il ne semble pas y avoir de moyen de l'interrompre, donc la condition while ne peut pas être vérifiée à nouveau et le programme ne peut pas quitter!
Y a-t-il une meilleure manière de faire cela? Ou un moyen d'interrompre la méthode de blocage?
la source
Réponses:
Vous pouvez appeler à
close()
partir d'un autre thread, et l'accept()
appel lancera unSocketException
.la source
close()
, je veux dire que cela lèvera l'exception en le faisant, alors y a-t-il un autre moyen (qui ne lève pas d'exception, pas non plus basé sur le délai d'expiration) pour arrêter d'écouter les demandes?readLine()
retournera alors null et les opérations de fermeture normales que le thread devrait déjà avoir en place se produiront.Activez le délai d'expiration
accept()
, puis l'appel expirera le blocage après l'heure spécifiée:http://docs.oracle.com/javase/7/docs/api/java/net/SocketOptions.html#SO_TIMEOUT
la source
L'appel est
close()
-ilServerSocket
une option?http://java.sun.com/j2se/6/docs/api/java/net/ServerSocket.html#close%28%29
la source
Vous pouvez simplement créer un socket "void" pour break serversocket.accept ()
Du côté serveur
Méthode pour interrompre le cycle du serveur
la source
La raison
ServerSocket.close()
lève une exception est que vous avez unoutputstream
ou uninputstream
attaché à ce socket. Vous pouvez éviter cette exception en toute sécurité en fermant d'abord les flux d'entrée et de sortie. Essayez ensuite de fermer le fichierServerSocket
. Voici un exemple:Vous pouvez appeler cette méthode pour fermer n'importe quel socket de n'importe où sans obtenir une exception.
la source
ServerSocket
mais à aSocket
et nous parlons de fermer leServerSocket
pas leSocket
, donc leServerSocket
peut être fermé sans fermerSocket
les flux de a.Utilisez serverSocket.setSoTimeout (timeoutInMillis) .
la source
OK, j'ai fait fonctionner cela d'une manière qui répond plus directement à la question du PO.
Continuez à lire après la réponse courte pour un exemple de fil de discussion sur la façon dont j'utilise cela.
Réponse courte:
Exemple du monde réel:
Dans cet exemple, j'ai un ServerSocket en attente d'une connexion à l'intérieur d'un thread. Lorsque je ferme l'application, je veux arrêter le thread (plus précisément, le socket) de manière propre avant de laisser l'application se fermer, donc j'utilise le .setSoTimeout () sur le ServerSocket puis j'utilise l'interruption qui est lancée après l'expiration du délai pour vérifier et voir si le parent essaie d'arrêter le thread. Si tel est le cas, je ferme le socket, puis un indicateur indiquant que le thread est terminé, puis je sort de la boucle Threads qui renvoie un null.
Ensuite, dans ma classe Controller ... (je montrerai uniquement le code pertinent, le masserai dans votre propre code si nécessaire)
J'espère que cela aidera quelqu'un sur la route.
la source
Une autre chose que vous pouvez essayer, qui est plus propre, est de vérifier un indicateur dans la boucle d'acceptation, puis lorsque votre thread d'administration veut tuer le blocage de thread sur l'acceptation, définissez l'indicateur (rendez-le thread safe), puis créez un socket client connexion à la prise d'écoute. L'acceptation arrêtera de bloquer et renverra la nouvelle socket. Vous pouvez élaborer un protocole simple indiquant au thread d'écoute de quitter proprement le thread. Et puis fermez le socket côté client. Aucune exception, beaucoup plus propre.
la source
Vous pouvez simplement passer la limite de délai (milli secondes) en tant que paramètre lors de l'appel de la fonction d'acceptation.
par exemple, serverSocket.accept (1000); ferme automatiquement la demande après 1 seconde
la source