Socket vs SocketChannel
J'essaie de comprendre SocketChannels, et NIO en général. Je sais comment travailler avec régulièrement des sockets et comment faire un simple thread par client-serveur (à l'aide de l'ordinaire des sockets blocage).
Donc mes questions:
- Qu'est ce qu'un SocketChannel?
- Qu'est-ce que les extra-je obtenir lorsque vous travaillez avec un SocketChannel au lieu d'une Prise de courant.
- Quelle est la relation entre un canal et un tampon?
- Qu'est ce qu'un sélecteur?
- La première sentance dans le la documentation est
A selectable channel for stream-oriented connecting sockets.
. Qu'est-ce que cela signifie?
J'ai lu aussi cette documentation, mais de toute façon je ne suis pas à l'obtenir...
- Je dois m'excuser pour les autres qui downvoted votre question en raison de l'arrière-plan et non le contenu. En tant que boursier de l'étudiant diplômé, je comprends tout à fait quand on est forcé de TA un cours qui n'est pas exactement dans votre domaine de recherche, en particulier lorsque votre financement en dépend. Je pense que c'est aussi bon que vous êtes venu ici pour demander des éclaircissements.
Vous devez vous connecter pour publier un commentaire.
Un
Socket
est un blocage périphérique d'entrée/sortie. Il fait leThread
qui est de l'utiliser pour bloquer sur le lit et, potentiellement, sur le bloc de l'écrit si le sous-jacent de la mémoire tampon est pleine. Par conséquent, vous devez créer un tas de différents threads si votre serveur a un tas d'ouvrirSocket
s.Un
SocketChannel
est un non-blocage de la lecture à partir de sockets, de sorte que vous pouvez avoir un fil de communiquer avec un tas de connexions ouvertes à la fois. Cela fonctionne en ajoutant un tas deSocketChannel
s à unSelector
, puis en boucle sur le sélecteur deselect()
méthode, qui peut vous avertir si les sockets ont été acceptées, les données reçues ou fermé. Cela vous permet de communiquer avec plusieurs clients dans un thread et ne pas avoir la surcharge de plusieurs threads et de synchronisation.Buffer
s sont une autre caractéristique de NIO qui vous permet d'accéder aux données sous-jacentes de lit et écrit pour éviter la surcharge de la copie de données vers de nouveaux tableaux.select()
et de perdre un thread entier. Il ne peut certainement pas être dit "non bloquant". Qu'entendez-vous par "pas de rappels en Java"? Avez-vous vuAsynchronousChannel
?Maintenant
NIO
est tellement vieux que peu de souvenir de ce que Java était comme avant 1.4, qui est ce que vous devez savoir pour comprendre le "pourquoi" deNIO
.En un mot, jusqu'à Java 1.3, toutes les I/O a été le blocage de type. Et pire, il n'y a rien d'analogue de la
select()
système d'appel à l'multiplex I/O. par conséquent, un serveur de mise en œuvre en Java n'avait pas le choix mais pour utiliser un "thread par connexion" stratégie de service.Le point de base de NIO, introduit dans Java 1.4, était de faire de la fonctionnalité traditionnelle de style UNIX multiplexé non-blocage I/O disponible en Java. Si vous comprenez comment programmer avec
select()
oupoll()
pour détecter les I/O de l'état de préparation sur un ensemble de descripteurs de fichiers (sockets, en général), alors vous aurez à trouver les services dont vous avez besoin pour que, dansNIO
: vous allez utiliserSocketChannel
s pour les non-blocage I/O points de terminaison, etSelector
s pour fdsets ou pollfd tableaux. Serveurs avec threadpools, ou avec les fils de la manipulation de plus d'une connexion à chaque, maintenant devenu possible. C'est le "extra".Un
Buffer
est le genre de tableau d'octets dont vous avez besoin pour socket non bloquant I/O, en particulier sur la sortie/écriture de côté. Si une partie seulement d'un tampon peut être écrit immédiatement, avec le blocage des I/O de votre fil sera simplement bloquer jusqu'à ce que la totalité peut être écrite. Avec les non-blocage I/O, votre fil est une valeur de retour de la façon dont beaucoup a été écrit, en laissant à vous de gérer la gauche de plus pour le prochain tour. UnBuffer
prend soin de ces détails de la mécanique explicitement à la mise en œuvre d'un producteur/consommateur motif de remplissage et de vidange, étant entendu que votre fils et la JVM du noyau pas être synchronisées.SocketChannel
est bloquant. Au moinsread()
etwrite()
méthodes. Le vrai, le non-blocage du canal estAsynchronousSocketChannel
, qui a été introduit dans Java 7.SocketChannel
en mode sans blocage est non bloquant. Asynchronous I/O est encore une autre bête, rien à voir avec le non-blocage de la mode que ce soit.select()
si vous souhaitez que vos données pour être prêt dès que possible. C'est ce que je voulais dire.Selector.select()
blocs. Ni leSocketChannel
ni sesread()
ouwrite()
méthodes bloc si le canal est en mode sans blocage, contrairement à ce que vous avez spécifiquement affirmé ci-dessus, où vous tort aussi d'un amalgame de non-blocage I/O avec e/s asynchrones.read()
etwrite()
. C'était il y a longtemps. Et je ne suis pas d'accord que non-blocage I/O n'a rien à avec I/O asynchrone. Ils ne sont pas les mêmes, mais ils sont étroitement liées.Même si vous utilisez
SocketChannels
, Il est nécessaire d'utiliser pool de threads pour traiterchannels
.Réflexion sur la scenairo-vous d'utiliser uniquement un fil qui est responsable à la fois d'interrogation
select()
et le traitement de laSocketChannels
sélectionnés à partir deSelectors
, si un canal prend 1 secondes pour le traitement, et il y a 10 canaux dans la file d'attente, cela signifie que vous devez attendre 10 secondes avant le prochain scrutin qui est untolerable. il devrait donc y avoir un pool de threads pour les chaînes de traitement.En ce sens, je ne vois pas de différence énorme pour le thread par client sockets blocage modèle. la différence majeure est dans
NIO
modèle, la tâche est plus petit, il ressemble plus à un thread par tâche, et les tâches de lecture, d'écriture, biz, etc. pour plus de détails, vous pouvez prendre un coup d'oeil à Netty's la mise en œuvre deNioServerSocketChannelFactory
, qui consiste à utiliser un Patron thread accepte la connexion, et de répartition des tâches à un pool de threads de travail pour le traitement desSi vous êtes vraiment de fantaisie à un fil, la ligne de fond est, au moins, vous shold ont mis en commun des I/O fils, parce que les opérations d'e/S est souvent oders de grandeur inférieure à celle de l'instruction des cycles de traitement, vous ne voulez pas le précieux un thread bloqué par I/O, et c'est exactement NodeJS faire, en utilisant un thread accepter la connexion, et tous les I/O sont asynchornous et d'être traitées en parallèle par le back-end de threads d'e/S de la piscine
est le style ancien thread par client morts?
Je ne le pense pas, NIO programmation est complexe et multi-threads n'est pas naturellement mauvais, Gardez à l'esprit que les systèmes d'exploitation modernes et CPU est devenu de mieux en mieux au multitâche, de sorte que les frais généraux de multithreading devient plus petit, au fil du temps.