7
votes

Y a-t-il un moyen de rouvrir une prise?

Je crée de nombreuses prises "à court terme" dans certains codes qui ressemblent à ce que: xxx

cela fonctionne bien, tant que nb est "petit" assez.

comme nb pourrait être assez grand cependant, j'aimerais faire quelque chose comme ça xxx

donc la question est de la question :
Y a-t-il un moyen de "réutiliser" une prise qui a été arrêtée?


0 commentaires

4 Réponses :


18
votes

Non, il s'agit d'une limitation des sockets C sous-jacents (et du protocole TCP / IP, à ce sujet). Ma question à vous poser est: pourquoi les éteignez-vous lorsque vous pouvez archiver votre application pour les utiliser?

Le problème avec de nombreux sockets à court terme est que la fermeture des points les met dans un état où ils ne peuvent pas être utilisés pour un tandis que (fondamentalement, deux fois la durée de vie du paquet, pour garantir que tous les paquets du réseau arrivent et sont jetés ou se sont rejetés par le réseau lui-même). Fondamentalement, ce qui se passe, c'est que, dans le 4 tuple qui doit être unique (source IP, port source, ip de destination, port de destination), le premier et les deux derniers ont tendance à toujours être le même, lorsque vous manquez de source Ports, vous êtes hosté.

Nous avons frappé ce problème dans le logiciel avant d'où il est devenu évident lorsque nous avons rencontré des machines plus rapides (puisque nous pourrions utiliser de nombreuses autres sessions).

Pourquoi ne vous ouvrez pas la prise et continuez à l'utiliser? Il semble que votre protocole est une simple demande / réponse, qui devrait être facile à faire avec cette approche.

quelque chose comme: xxx

< em> update:

une possibilité (et nous l'avons déjà fait auparavant) si vous êtes à court de connexion en raison de cette open / proche continue, est de détecter le problème et de l'accélérer . Considérons le code suivant (les trucs que j'ai ajoutés sont plus pseudo-code que Python car je n'ai pas touché Python pendant un certain temps): xxx

essentiellement, il laisse Vous courez à pleine vitesse alors qu'il y a beaucoup de ressources, mais ralentit lorsque vous frappez votre problème. C'est en fait ce que nous avons fait à notre produit à "corriger" le problème de l'échec lorsque les ressources ont été faibles. Nous l'aurions réacheminect, à l'exception du fait qu'il s'agissait d'un produit hérité qui approche de la fin de la vie et nous étions fondamentalement au mode de coût minimal de service.


4 commentaires

J'aimerais pouvoir faire ça, mais malheureusement, je dois arrêter la prise (ou au moins «demi-ferme») sinon les blocs d'appel d'envoi et je n'ai jamais la réponse. Je suppose que si je ne ferme pas la prise, le serveur ne sait pas que j'ai terminé l'envoi de données et l'attend d'autres.


Vous devriez réécrire le serveur puis pour l'obtenir d'utiliser une approche plus "sensible" basée sur des délimiteurs dans le flux de données (par exemple). Mais il y a une autre possibilité - voir ma mise à jour pour une approche que nous avons prise pour résoudre le problème.


@PAX: J'ai mis en œuvre votre solution et cela fonctionne très bien pour tout "NB". Merci beaucoup.


Aucun problème, @DUGRES, il fonctionne toujours bien pour notre produit héritage également, malgré le fait qu'il était fini il y a environ 2 ans. Certains clients ne peuvent tout simplement pas abandonner le passé :-)



1
votes

Si vous continuez à ouvrir et à fermer les sockets pour le même port, il est préférable d'ouvrir cette prise une fois et de la garder ouverte, alors vous aurez beaucoup de meilleures performances, car l'ouverture et la fermeture prendront du temps.

Si vous avez de nombreuses prises à court terme, vous pouvez également envisager des sockets de datagramme (UDP). Notez que vous n'avez pas de garantie d'arrivée dans ce cas, l'ordre des paquets n'est pas garanti.


0 commentaires

3
votes

Je ne suis pas sûr de ce que le surcharge supplémentaire serait comme, mais vous pouvez complètement fermer et rouvrir la prise. Vous devez définir SO_REUSEADDRDDRDR et se lier à un port spécifique que vous pouvez réutiliser.

sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sck.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)


1 commentaires

Juste ce dont j'avais besoin. J'ai oublié de créer une nouvelle instance de socket pour la réouverture. Faites attention à la création d'une nouvelle instance de socket, sinon vous obtiendrez une erreur «Bad File Descripteur».



0
votes

Vous ne pouvez pas réutiliser la prise, mais cela ne vous aiderait pas si vous le pouviez, puisque vous êtes à court de ports, pas de sockets. Chaque port restera dans time_wait état Pour deux fois la durée maximale du segment après avoir initié l'arrêt. Il serait préférable de ne pas nécessiter tant de ports dans une période aussi courte, mais si vous devez utiliser un grand nombre, vous pourrez peut-être augmenter le Gamme de ports éphémères .

Les numéros de port sont de 16 bits et donc il n'y en a que 65536. Si vous êtes sous Windows ou Mac OS X, des ports éphémères sont choisis par défaut à partir de la plage 49152 à 65535. Il s'agit du Gamme officielle désignée par IANA , mais sur Linux et Solaris (souvent utilisés pour les serveurs de trafic élevés), la plage par défaut commence à 32768 pour permettre plus de ports. Vous voudrez peut-être effectuer une modification similaire à votre système s'il n'est pas déjà défini de cette façon et vous avez besoin de ports plus éphémères.

Il est également possible de réduire la durée de vie maximale du segment sur votre système, ce qui réduit la quantité de temps que chaque prise est dans time_wait état ou pour utiliser SO_REUSeADDRDRDR SO_LINGER Dans certains cas pour réutiliser les ports avant l'expiration du temps. Cependant, cela peut au moins provoquer des connexions plus anciennes à mélanger avec de nouvelles connexions qui utilisent le même numéro de port, si certains paquets provenant des connexions plus anciennes sont lents, il n'y a généralement pas une bonne idée.


2 commentaires

C'est un piratage vraiment terrible. Mieux vaut simplement garder la prise ouverte et continuer à l'utiliser.


Vous ne pouvez continuer que l'utilisation de l'utilisation si le protocole est conçu pour supporter cela, et toutes les connexions sont au même endroit. Bien sûr, c'est mieux si vous pouvez le faire, mais l'OP a dit que le serveur exige que la connexion soit fermée avant de réagir.