Socket Bind Erreur
J'ai une application de test qui ouvre un socket , envoie quelque chose par le biais de cette prise et puis le referme . Ceci est fait dans une boucle de 5 à 10.000 fois. La chose est que, après 3,4000 itérations j'obtiens une erreur de ce type :
java.net.BindException: Address already in use: connect
J'ai même mis le socket à utiliser immediattly, mais l'erreur persiste
try
{
out_server.write(m.ToByteArray());
socket_server.setReuseAddress(true);
socket_server.close();
}
catch(Exception e)
{
e.printStackTrace();
System.out.println(i+" unable to register with the server");
}
Ce que je pourrais faire pour résoudre ce problème ?
OriginalL'auteur klaus johan | 2009-07-06
Vous devez vous connecter pour publier un commentaire.
Je pense que vous pouvez peut-être aller trop vite.
La plupart des systèmes d'exploitation ont une limite sur le nombre de sockets ils peuvent avoir de l'ouvrir à tout moment, mais c'est en fait pire que ça.
Lorsqu'un socket est fermé, il est mis dans un état time-wait pour un certain laps de temps. C'est généralement deux fois le paquet de temps-à-vis de la valeur et permet de s'assurer qu'il n'y a pas encore de paquets dans le réseau qui sont sur le chemin de votre support.
Une fois que le temps expire, vous pouvez être sûr que tous les paquets dans le réseau sont déjà morts. Le support est placé dans cet état particulier, de sorte que les paquets qui ont été dans le réseau lorsque vous l'éteignez peuvent être capturés et jetés s'ils arrivent avant qu'ils meurent.
Je pense que c'est ce qui se passe dans votre cas, les prises ne sont pas libéré aussi rapidement que vous le pensez.
Nous avons eu un problème similaire avec le code qui ouvre beaucoup de courte durée des séances. Il fonctionnait très bien pour un tout, mais alors le matériel obtenu plus rapidement, ce qui de beaucoup plus pour être ouvert dans une période de temps donnée. Cela s'est manifesté comme l'incapacité d'ouvrir plusieurs sessions.
Une façon de vérifier cela est de faire
netstat -a
à partir de la ligne de commande et de voir combien de séances sont en fait dans l'état d'attente.Si ce n'est à son tour d'être le cas, il existe quelques façons de le gérer.
Ce dernier point mérite une certaine expansion. Nous avons en fait un back-off de la stratégie dans notre mentionnées ci-dessus de l'application qui permettrait de réduire progressivement la charge sur un fournisseur de ressources si elle a été se plaindre si, au lieu de 30 à deux secondes de retard, nous avons opté pour un retard d'une seconde, puis deux secondes, puis quatre et ainsi de suite.
Le processus général pour un back-off de la stratégie est comme suit et il peut être utilisé dans tous les cas où il peut y avoir des pénuries temporaires d'une ressource. L'action fait allusion dans le pseudo-code ci-dessous, serait l'ouverture d'un socket dans votre cas.
Cela permet au processus de fonctionner à pleine vitesse dans la grande majorité des cas, mais recule lorsque des erreurs se produit pour la première fois, espérons-le, de donner le fournisseur de ressources de temps pour récupérer. L'augmentation progressive des retards permet plus graves restrictions de ressources et récupérer le maximum tente captures de ce que vous appelleriez des erreurs permanentes (ou d'erreur de prendre trop de temps à récupérer).
Il n'est pas toujours une bonne idée de jouer avec ces paramètres. La plupart devraient être à l'écoute pour le réseau characteistics et puis, votre application doit être à l'écoute pour que. La réduction de time_wait, sans réduire le time-to-live entraînera les parasites des paquets arrivant. Réduction de la TTL au point où les paquets ne peuvent pas atteindre la destination signifie beaucoup de perte de paquets. Idéalement, vous devriez conserver les connexions ouvertes (manuellement ou avec un pool de connexion) ou régler vos applications de comportement (comme avec un retard mentionné par @Stu dans sa réponse).
OriginalL'auteur paxdiablo
Mes suggestions:
@Pax a un bon point sur l'état de la prise par la suite. Tentez votre code, ne parviennent pas laisser, et puis faire un
netstat
et de les analyser (ou post ici)OriginalL'auteur Stu Thompson
Ce système d'exploitation? Si vous utilisez windows, et je devine que vous êtes, alors il y a une limite pour le nombre de connexions client que vous pouvez avoir (il est configuré par le
MaxUserPort
entrée de registre qui se trouve juste à être 4000 par défaut; voir http://technet.microsoft.com/en-us/library/aa995661.aspx et http://www.tech-archive.net/Archive/Windows/microsoft.public.windows.server.general/2008-09/msg00611.html pour les détails de changer). Cela, couplé avec le fait que vous êtes de l'initiation de la prise près de votre client et donc l'accumulation des sockets enTIME_WAIT
état de votre client est probablement la cause de votre problème.Veuillez noter que la solution à la
TIME_WAIT
accumulation question n'est PAS de jouer avec la pile TCP de paramètres pour rendre le problème.TIME_WAIT
existe pour une très bonne raison de le retirer ou de le raccourcir sera susceptible de vous causer de nouveaux problèmes!Donc, en supposant que vous êtes sur une machine Windows, la première étape est de régler votre
MaxUserPort
valeur, de sorte que vous avez plus de ports dynamiques, disponibles pour vos connexions sortantes. Ensuite, si cela n'a pas arranger les choses pour vous, vous pouvez penser sur le côté de la connexion devrait se terminer avec laTIME_WAIT
(en supposant que vous pouvez contrôler le protocole utilisé sur vos connexions...) par Les pairs que les questions de la "fermeture active" est celui qui se termine avec leTIME_WAIT
donc, si vous pouvez changer les choses pour que votre serveurs problème la fermeture active ensuite leTIME_WAIT
prises s'accumulent sur le serveur plutôt que sur le client et ce PEUT être mieux pour vous...Il n'y a pas de limite pour les connexions entrantes.
Notez que cela ne fonctionne que sur les clients Windows par XP, et les serveurs par le biais de 2003. Vista et Server 2008 et au-dessus de l'utilisation d'une nouvelle implémentation de TCP/IP, et vous avez besoin d'utiliser
netsh interface ipv4 show dynamicportrange tcp
à montrer, et un correspondantset
de commande, de modifier ces valeurs. Windows 7 Enterprise ordinateur que j'avais à la main a 16384 dynamique des ports disponibles par défaut, en grande partie à la suppression de cette limitation.OriginalL'auteur Len Holgate
Je suis d'accord avec les autres que vous êtes à court de douille d'extrémité. Cependant, ce n'est pas 100% en cristal clair de vous exemple car on peut supposer que l'exception est à venir à partir d'un connect() ou appel de bind() qui peuvent être à l'origine de quelques autres de haut-niveau de la méthode Java.
Il convient également de souligner que l'exécution de points de terminaison n'est pas une sorte de bizarre restriction de la prise de la bibliothèque, mais un joli élément fondamental de toute implémentation de TCP/IP. Vous avez besoin de garder des informations sur les anciennes connexions autour pour un peu de temps pour que le retard dans l'arrivée des paquets IP pour un vieux de connexion sont supprimés.
setReuseAddress() correspond à la SO_REUSEADDR option de socket et s'applique uniquement sur le serveur quand il fait un listen().
OriginalL'auteur George Phillips
Je pense que c'est le même que celui de la question (et je l'ai relié à ma réponse, qui, je pense, pourrait éventuellement vous aider.)
Java Se Lier D'Exception
OriginalL'auteur poundifdef
Si l'exemple de code est en fait la façon dont vous êtes l'exécution de la boucle, vous pouvez avoir des choses dans le mauvais ordre.
La java docs pour setReuseAddress dire: Le comportement lors de l'SO_REUSEADDR est activé ou désactivé après une socket est lié (Voir isBound()) n'est pas défini.
Essayez de déplacer l'appel à quelque part avant de bind() ou connect().
OriginalL'auteur Duck
peu de temps après à l'aide d'une douille.close() ne fermera pas prise immédiatement et la boucle s'exécute (en boucle, il tente la connexion de socket witrh même adresse ip et port ) beaucoup plus vite merci donc de nulle du support.
socket_server.close();
socket_server = null;
Merci
Sunil Kumar Sahoo
OriginalL'auteur Sunil Kumar Sahoo