Est un OutputStream en Java blocage? (Sockets)
Je suis en train d'écrire naïf code réseau pour un projet et un pote m'a laissé entendre à la possibilité que lorsque j'envoie un paquet d'informations à partir du serveur à tous les clients dans un mode itératif, je pourrais obtenir intense de latence lorsque l'un des clients n'est pas de répondre correctement.
Il est réputé pour la pêche à la traîne, donc j'étais un peu sceptique lors de l'exécution d'un thread secondaire qui est responsable aujourd'hui d'envoyer des données à un client, avoir une file d'attente que le Serveur ajoute simplement les paquets qui est ensuite lu par le fil pour envoyer des données.
La question, j'ai maintenant après réflexion, c'est le temps ou pas l'OutputStream de Java Prise en fait les files d'attente les trucs qu'il veut envoyer par lui-même, éliminant ainsi la nécessité d'une file d'attente à l'avance. La possibilité de disposer d'intenses problèmes atteint son apogée uniquement lorsque le Serveur est bloquante tant qu'il n'a pas obtenir une réponse à partir d'un client de l'objet envoyé a été reçu.
Grâce.
OriginalL'auteur salbeira | 2012-05-13
Vous devez vous connecter pour publier un commentaire.
Bien sûr, quand vous écrivez à un socket, cette écriture est mis en mémoire tampon. Socket objet
setSendBufferSize()
méthode pour la définition de cette taille de la mémoire tampon. Si votre écriture peut être mis en cache dans cette mémoire tampon, puis, bien sûr, vous pouvez itérer immédiatement sur la suite de la prise. Sinon ce tampon doivent être vidées dans le client immédiatement. Ainsi, durant le rinçage, vous allez être bloqué. Si vous voulez éviter d'être bloqué, tout en vidant la mémoire tampon, vous devez utiliser unSocketChannel
non blocage I/O.De toute façon, la meilleure option pour l'écriture de nombreux socket simultanément, est de gérer chaque support avec un thread différent, de sorte que toutes les écritures peuvent être exécutées en même temps.
Même si Tomasz post était un meilleur exemple c'est exactement ce que je cherchais, en termes d'explication EJP. Je vous remercie beaucoup.
OriginalL'auteur eppesuig
Votre ami a raison, mais il a plus à voir avec la façon dont tcpip protocole fonctionne. Largement simplifier les paquets envoyés au client doivent être confirmés. Si le client ne répond pas (ne lit pas les données entrantes, l'ordinateur est sous une charge lourde, etc.) le serveur ne pas recevoir les accusés de réception et d'arrêter d'envoyer les données. Ce mécanisme intégré dans le protocole TCP/IP empêche l'une des extrémités de la communication de l'envoi de grandes quantités de données sans s'assurer que l'autre extrémité reçu. Dans les virages c'éviter l'obligation de renvoyer les grandes quantités de données.
En Java c'est ce qui manifeste que le blocage de l'écriture à
OutputStream
. Le sous-jacentes de la pile TCP/IP/système d'exploitation ne permet pas l'envoi de davantage de données jusqu'à ce que le client est prêt à le recevoir.Vous pouvez facilement tester cette! J'ai mis en place simple serveur accepte la connexion, mais ne parvient pas à lire les données entrantes:
Et un client simple qui se contente d'envoyer autant de données qu'il peut en 4K lots:
Le client boucle d'accroche sur mon ordinateur au bout de 95 itérations (votre kilométrage peut varier). Cependant, si j'ai lu de
inputStream
dans le thread du serveur - la boucle va sur et sur.OriginalL'auteur Tomasz Nurkiewicz
Un OutputStream est bloquant. Il possède probablement une mise en mémoire tampon, mais cela ne vous aidera pas beaucoup si le serveur n'est jamais consommer octets (fixe tampon finira par se remplir). Si votre ami a raison, vous avez besoin d'écrire dans un thread séparé, ou utiliser quelque chose de plus avancé, comme nio.
Sur la lecture de la côte, vous pouvez utiliser les() pour éviter le blocage. Pas de correspondance d'appel sur l'écriture de côté. Je souhaite qu'il y était.
OriginalL'auteur Keith Randall