2010-10-26 29 views
4

J'ai un serveur d'E/S de socket non bloquant à un seul thread écrit en Java en utilisant nio.fermeture d'un canal de socket de manière asynchrone

Lorsque j'ai fini d'écrire sur une connexion, je souhaite la fermer.

La fermeture du canal signifie-t-elle bloquant jusqu'à ce que toutes les écritures tamponnées aient été acquittées par le destinataire?

Il serait utile de savoir si, lors de la fermeture asynchrone, il a réussi ou non, mais je pourrais vivre avec toutes les erreurs dans la fermeture étant ignorée.

Y a-t-il un moyen de configurer ceci, par ex. avec setSoLinger() (et quels paramètres seraient appropriés?)

(Une discussion générale au-delà de Java sur Linux et autres systèmes d'exploitation à cet égard serait utile)

Répondre

3

La fermeture en mode non bloquant est non bloquante.

Vous pouviez mettre le canal en mode blocage, définir un délai d'attente positif et le fermer, et bloquer le délai d'attente pendant que le tampon d'envoi du socket était vidé, mais hélas, Java ne lançait pas d'exception Si le délai d'expiration expire, vous ne pouvez pas savoir si toutes les données ont disparu. J'ai signalé ce bug il y a dix ans ou plus et il est revenu "ne va pas réparer" à cause de problèmes de compatibilité. Si vous pouvez attendre jusqu'à ce que Java 7 sorte, je crois que les choses de nio2 ont ce problème, je l'ai certainement demandé, mais qui sait quand cela sera?

Et même si vous avez tout cela, tout ce que vous savez, c'est que les données ont été envoyées. Vous ne savez rien de ce qui a été reçu ou traité par l'application destinataire. Si vous en avez besoin, vous devez le construire dans votre protocole d'application.

+1

merci beaucoup, la confirmation de ma compréhension que je cherchais! – Will

1

Je ne sais pas ce qui se passe vraiment, mais je sais que close() inclut flush() (sauf dans PrintStream et PrintWriter ...). Donc, mon approche serait d'ajouter les connexions à proximité d'une file d'attente et de traiter cette file dans un deuxième thread (y compris la gestion des erreurs).

Je comprends que votre serveur est mono-thread, mais un deuxième thread ne coûte pas beaucoup, la complexité du problème est faible et la solution sera facile à comprendre toute maintenance.

+0

Le filetage simple est à filetage unique est à filetage unique – Schildmeijer

+0

@Schildmeijer: La réalité l'emporte toujours sur les règles. –

+1

le flush dans la clôture semble familier des courants d'IO classiques; mais est-ce vrai aussi des canaux? – Will