citant de Ce didacticiel de prise : P>
Les prises sont en deux saveurs primaires. Une prise active est connectée à un Prise active à distance via une donnée ouverte connexion ... une prise passive est non connecté, mais aussi attendre un connexion entrante, qui va fraye une nouvelle prise active une fois par La connexion est établie ... p>
Chaque port peut avoir un seul passif socket se lié, en attente connexions entrantes, et Plusieurs sockets actifs, chacun correspondant à une ouverture connexion sur le port. C'est comme si L'agent d'usine attend de nouveau messages à arriver (il représente la prise passive), et quand une Le message arrive d'un nouvel expéditeur, il initie une correspondance (un connexion) avec eux par déléguer quelqu'un d'autre (un actif socket) pour lire réellement le paquet et répondre à l'expéditeur si nécessaire. Cela permet l'usine travailleur à être libre de recevoir de nouveaux paquets. ... p> blockQuote>
Ensuite, le didacticiel explique qu'après une connexion établie, la prise active continue de recevoir des données jusqu'à ce qu'il n'y ait pas d'octets restants, puis ferme la connexion. P>
Ce que je n'ai pas compris, c'est ceci: Supposons qu'il y ait une connexion entrante au port, et l'expéditeur veut envoyer de petites données toutes les 20 minutes. Si la prise ferme la connexion actif en l'absence d'octets restants, l'expéditeur peut se reconnecter au port chaque fois qu'il veut envoyer des données? Comment pouvons-nous persistons une connexion établie une fois pour plus longtemps? Pouvez-vous me dire ce que je suis absent ici? P>
Ma deuxième question est, qui détermine la limite des prises actives qui travaillent en même temps? p>
3 Réponses :
L'expéditeur doit envoyer un paquet de conserve à intervalles réguliers pour garder la connexion en vie. Le format du Keepalive dépend du protocole. Cela pourrait être aussi petit qu'une seule nulle dans le segment de données TCP. P>
quant à la deuxième question ... Cela dépend de l'E / S. S'il bloque des E / S, vous ne voulez que un certain nombre de threads exécutant sur votre ordinateur, vous ne pourrez donc pas avoir de nombreux clients. Si c'est non bloquant, vous pouvez avoir beaucoup plus de clients. Les langages de programmation doivent avoir la prise en charge des E / S bloquants et non bloquants. (Je sais pour un fait que Java fait.) P>
Cela dépend également des choses comme la bande passante, le transfert de données pour chaque client, la mémoire, la vitesse d'horloge, etc. mais non bloquante vs bloquant peut faire une énorme différence dans le nombre de clients que vous pouvez accepter. Vous ne pouvez probablement pas avoir plus de 5 à 10 clients bloquant sans votre serveur qui se bloque ... mais vous pouvez avoir des milliers de personnes si vous ne bloquez pas. P>
Ainsi, vous envoie continuellement ces paquets de conserve pendant 20 minutes une opération moins chère que la rétablissement de la connexion à chaque fois? Quels seraient les avantages de garder la connexion en vie, en plus de l'échapper à la surcharge de la ré-connexion?
En fait, si vous aurez beaucoup de clients connectant et que chaque demande sera rapide (20 secondes comme indiqué), il est préférable d'utiliser un modèle de type de demande / réponse. Vous n'avez que 64k ports disponibles, ce qui signifie seulement 64k sockets peut être accepté sur une adresse IP avant d'obtenir l'épuisement des ports à moins que ces sockets soient fermés. Cela dépend vraiment de votre application cependant. Si vous écrivez un MMO par exemple, vous avez besoin de connexions persistantes. Si vous écrivez un serveur Web, bien que vous n'ayez pas besoin (et que vous essayez d'éviter) les connexions persistantes (sauf si vous utilisez HTML5 mais c'est une histoire différente).
Depuis le point de vue du client, un simple service de garde à un seul serveur n'a pas beaucoup de travail. Vous envoyez probablement déjà une demi-douzaine de conserves régulièrement lorsque vous êtes connecté à Internet. Dans le point de vue du serveur, il peut être avantageux de conserver au minimum le nombre de sockets dans sa liste de sockets pour améliorer les performances d'E / S. Si c'est aussi longtemps qu'une attente de 20 minutes entre les transferts de données, je créerais une nouvelle connexion à chaque fois. C'est négligeable pour le client, mais pas pour le serveur.
@ kTM5124 +1 pour indiquer que c'est que c'est beaucoup plus cher pour le serveur de créer une connexion que le client. Multiplié par des centaines de clients et devient un goulot d'étranglement.
J'ai compris. Une chose de plus que je veux préciser: si j'ai 64k ports disponibles et si je peux reproduire plus d'une prise de courant active pour chaque port (si j'ai des connexions entrantes différentes du même port), je peux théoriquement accepter plus de 64k sockets, droit?
Vous ne pouvez accepter que 64k connexions simultanément i> afin que certains des clients déposent, vous n'atteignez pas l'épuisement des ports. De plus, seules les prises passives peuvent accepter et vous ne pouvez avoir qu'une seule prise passive associée à une paire IP / Port afin que vous ne puissiez pas écouter avec une prise, mais de nombreuses prises peuvent se connecter.
Oh alors je me suis tellement expliqué, ce que je voulais dire, suppose que je commence un fil pour effectuer FOO () chaque fois qu'une prise passive accepte une connexion. Comme il y a une douille passive pour chaque port, je peux avoir max. 64K prises simultanément, mais peut-être plus de 64 000 threads effectuant FOO (), en fonction de la fin de la foo () S. Maintenant, il est plus clair, THX GUYS:]
Ah, oui, ce que tu as dit est absolument correct. C'est là qu'un mécanisme de file d'attente et un threadpool sont utiles. Vous pouvez également utiliser une variante du modèle de commande de cette manière où vos gestionnaires de commande sont les gestionnaires de réponse et que votre motif de commande est implémenté à l'aide d'une threadpool.
@Srm "Vous avez uniquement des ports 64K disponibles, ce qui signifie que seulement 64k sockets peuvent être acceptés sur une adresse IP". Comme l'OP cité, 1 port comporte 1 prise passive et de nombreuses prises actives, avec chaque prise active pour chaque connexion. Pourquoi mentionnez-vous ici 64k Port ici?
@tropy, je parlais de l'épuisement du port TCP / IP et du fait que lorsque vous acceptez une prise, il est attribué un numéro de port aléatoire unique. Cela fait partie du protocole TCP / IP - l'adresse et le port identifient de manière unique cette connexion. Étant donné que le port est de 16 bits Numéro non signé le plus grand nombre de ports ouverts (par conséquent, les connexions ouvertes sur un seul port d'écoute) sont 65535. Les serveurs hautes performances troncent comme une copie zéro des prises et de telle sorte que c'est une limite difficile dans le protocole.
première question: Oui, une fois qu'une prise est fermée, vous devez faire une ouverture à nouveau pour retraduire la communication. P>
Deuxième question: Tu fais. Si vous souhaitez que vous puissiez créer des connexions 64K à votre serveur et subir une épuisement du port (je ne le recommande pas). Comme KTM5124 a déclaré, tout dépend de votre application. Il existe différentes façons de rendre votre serveur évolutif, notamment à l'aide d'ASYNC E / S et d'un pool de threads pour gérer les demandes du client. P>
S'il vous plaît voir la réponse de Will Stackoverflow.com/a/2332756/1418457 Peut-être que vous mal comprenez quelque chose à propos de TCP
Ok, si l'épuisement du port TCP / IP est une chose côté client uniquement (comme intimée par la limite 64k par client par port de serveur), alors pourquoi existe-t-il un problème mondial réel de l'épuisement des ports sur des serveurs? Vous pouvez toujours utiliser toutes les valeurs du tuple - peut-être que mon numéro 64K est faux, mais il y a une limite difficile au nombre de combinaisons que tuiles pouvant contenir. Lorsque vous manquez de combinaisons, à moins que vous n'ayez pas réutilisé adresse, vous manquerez d'adresses (TUPLE UNIQUE VRAIMENT) pour attribuer la connexion incommodé et la connexion est refusée.
Veuillez ne pas confondre les paquets réels envoyés par la mise en œuvre TCP / IP sur le réseau et l'interaction entre votre programme et une bibliothèque implémentant TCP / IP. P>
La prise est juste une abstraction présentée à votre programme par la mise en œuvre TCP / IP (Bibliothèque ou OS Kernel OS). Vous pouvez visualiser la prise comme connexion au tuyau (localIP: Port-RootiP: Port). Votre programme ouvre une prise, communique des données sur la prise et peut fermer la prise si ce n'est plus nécessaire pour aider les ressources gratuites. C'est un flux normal. Toutefois, la mise en œuvre TCP / IP peut fermer la prise pour ses propres raisons valables. Certaines de ces raisons: la déconnexion du câble d'accès réseau, les erreurs de routage réseau, le serveur est tombée en panne, etc. Ainsi, votre programme peut trouver un socket TCP / IP fermé même s'il ne la fermait pas. p>
Maintenant votre première question, que dois-je faire si mon programme envoie de petites segments de données avec une longue pause entre eux. La réponse est la suivante: dépend de combien de temps la pause et de quel programme vous écoutent de l'autre côté. La plupart des implémentations TCP / IP ont une notion de temps de connexion pour vous fournir des abstractions de connexion fiable sur de véritables réseaux peu fiables. Ainsi, si votre programme mettra une pause plus longue que le délai d'attente TCP / IP, votre prise a été fermée par la bibliothèque et vous aurez besoin de ré-ouvrir la prise. Cela peut également causer à nouveau de redémarrer la communication, dépend d'un programme qui écoute pour vous de l'autre côté du tuyau de connexion TCP / IP. P>
Il existe des moyens d'augmenter le délai d'attente TCP / IP et de le garder en vie. Ceux-ci peuvent être effectués dans le cadre de la configuration du réseau, la configuration du logiciel de serveur à l'autre extrémité ou par vous demander explicitement à garder la prise ouverte en définissant les paramètres Keepalive dans votre appel de la bibliothèque TCP / IP. Serait-il toujours ouvert ou pas dépend. Les détails complets sur la façon dont TCP / IP garderait la prise ouverte ne devrait pas vous confondre car il n'a rien à voir avec votre code. TCP / IP a de nombreux paramètres et des délais d'attente différents pour fournir à votre programme une illusion d'une connexion fiable stable. La bonne partie est tout cachée de votre code de programme tant que vous n'en abusez pas. Gardez votre pause sous quelques secondes :) Un ensemble de réglages de délai d'attente peut bien fonctionner pour de petites applications de réseau local fiable et ne fonctionnera pas pour des applications de charge élevées ou sur une connectivité continue continue. Chaque situation spécifique a sa propre solution, souvent plus qu'une seule. P>
Dans cette question spécifique "Envoyer une petite donnée toutes les 20 minutes" Je vous conseillerais de fermer et d'ouvrir une connexion de socket pour chaque communication. Le temps d'ouvrir l'un est inférieur à une seconde et ne devrait pas avoir une incidence sur votre communication. En retour, vous obtenez moins de complexité dans votre protocole de communication. Le récepteur est toujours disponible sur une nouvelle connexion à la prise et les deux systèmes peuvent profiter de ressources gratuites de la communication TCP / IP sur toutes les 20 minutes lorsque vous n'en avez pas besoin. P>
Vous êtes paraphrasant cet article et des bits et des morceaux de différentes sections de l'article. Les contextes sont différents. Dans la dernière section, l'auteur explique son programme. Les sockets n'agissent pas comme celle-ci par défaut, en fait, si vous oubliez de fermer votre prise de mauvaise qualité, les choses peuvent-elles arriver et arriveront. La prise ne ferme pas automatiquement quand elle reçoit le dernier octet.
Ok, je pensais que c'est la convention et je viens de me demander ce que je manque ici. Je suis nouveau dans les concepts et c'est pourquoi je veux remettre en question tout ce que je trouve difficile à comprendre.
Pas de problème, je voulais juste m'assurer que vous comprenez que vous devez expliquer explicitement la prise. Cela pourrait vous faire sauver des maux de tête dans la ligne lorsque vous vous grattez la tête en essayant de déterminer pourquoi la prise n'a pas fermé :).