socket java / flux de sortie écrit: ils bloquent?

voix
31

Si je ne fais que ECRIS à une prise sur un flux de sortie, sera jamais bloquer? Lit ne peut bloquer, non? Quelqu'un m'a dit peut bloquer , mais écrit - je vois seulement une caractéristique de délai d' attente pour la méthode de lecture d'une prise - Socket.setSoTimeout().

Il ne fait pas de me sens qu'une écriture pourrait bloquer.

Créé 27/08/2009 à 05:44
source utilisateur
Dans d'autres langues...                            


2 réponses

voix
45

Une écriture sur un socket peut bloquer aussi, surtout si elle est un Socket TCP. Le système d' exploitation ne tampon une certaine quantité de données non transmises (ou transmis mais non acquittés). Si vous écrivez des choses plus vite que l'application à distance est capable de le lire, la prise finira par sauvegarder et vos writeappels bloque.

En réponse à ces questions de suivi:

Donc, il y a un mécanisme permettant de définir un délai pour cela? Je ne suis pas sûr de ce comportement, il faudrait ... peut-être jeter données si les tampons sont pleins? Ou peut-être supprimer des données plus anciennes dans la mémoire tampon?

Il n'y a pas de mécanisme pour définir un délai d' attente d'écriture sur un java.net.Socket. Il y a une Socket.setSoTimeout()méthode, mais elle affecte accept()et read()appelle ... et non des write()appels. Apparemment, vous pouvez obtenir écrire les délais d' attente si vous utilisez NIO, mode non-bloquant, et un sélecteur, mais ce n'est pas aussi utile que vous pouvez l' imaginer.

Une pile TCP correctement mis en œuvre ne rejette pas les données mises en mémoire tampon à moins que la connexion est fermée. Toutefois, lorsque vous obtenez un délai d' attente d'écriture, il est certain que les données qui sont actuellement dans les tampons au niveau du système d'exploitation a été reçu par l'autre bout ... ou non. L'autre problème est que vous ne savez pas à quel point les données de votre dernière writea été effectivement transféré à OS niveau des tampons de pile TCP. En l' absence d' un protocole de niveau d'application pour resynchronisation le flux * , la seule chose sûre à faire après un délai d' attente sur writeest d'arrêter la connexion.

En revanche, si vous utilisez un socket UDP, les write()appels ne seront pas bloquer pour une période de temps significative. Mais l'inconvénient est que s'il y a des problèmes de réseau ou l'application à distance ne suit pas la, les messages seront supprimés sur le sol sans notification à chaque extrémité. De plus, vous pouvez constater que les messages sont parfois livrés à l'application à distance sur commande. Ce sera à vous (le développeur) pour traiter ces questions.

* Il est théoriquement possible de le faire, mais pour la plupart des applications , il n'a pas de sens de mettre en œuvre un mécanisme de resynchronisation supplémentaire sur le dessus d'un déjà fiable (à un point) flux TCP / IP. Et si cela avait du sens, vous devez aussi faire face à la possibilité que la connexion fermée ... il serait plus simple de supposer fermée.

Créé 27/08/2009 à 06:04
source utilisateur

voix
7

La seule façon de le faire est d'utiliser NIO et sélecteurs.

Voir la writeup de l'ingénieur Sun / Oracle dans ce rapport de bogue: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4031100

Créé 15/07/2011 à 16:09
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more