WCF: système.Net.SocketException - une seule utilisation de chaque adresse socket (protocole/adresse réseau/port) est normalement autorisée

j'ai un service WCF et une application Web. Web application fait des appels à ce service WCF d'une manière continue A. K. un sondage. Dans notre environnement de production, je reçois très rarement cette erreur. Puisqu'il s'agit d'une activité interne, les utilisateurs n'étaient pas au courant du moment où cette erreur est lancée.

ne pouvait pas se connecter à http://localhost/QAService/Service.svc . Code D'erreur TCP 10048: une seule utilisation de chaque adresse de prise (protocole/adresse réseau/port) est normalement autorisé 127.0.0.1: 80. ---> Système.Net.WebException: impossible de se connecter au serveur distant ---> Système.Net.Douilles.SocketException: Une seule utilisation de chaque adresse socket (protocole/adresse réseau/port) est normalement autorisé 127.0.0.1: 80

j'ai de la difficulté à reproduire ce comportement dans notre environnement de développement/assurance de la qualité. J'ai fait en sorte que la connexion client soit fermée lors d'un essai..attraper..enfin bloc. Je ne comprends toujours pas ce qui cause ce problème .. tout un courant de cela?

Note : j'ai regardé cette donc question , mais ne semble pas répondre à mon problème, il ne s'agit donc pas de questions répétées.

38
demandé sur Community 2009-08-27 10:12:36

2 réponses

vous surchargez la pile TCP/IP. Windows (et je pense que toutes les piles de socket en fait) ont une limitation sur le nombre de sockets qui peuvent être ouverts en séquence rapide en raison de la façon dont les sockets se ferment en fonctionnement normal. Chaque fois qu'une socket est fermée, elle entre dans L'état TIME_WAIT pendant un certain temps (240 secondes IIRC). Chaque fois que vous sondez, une socket est consommée hors de la plage dynamique par défaut( je pense que c'est environ 5000 ports dynamiques juste au-dessus de 1024), et chaque fois que ce sondage se termine, que une socket particulière entre dans TIME_WAIT. Si vous pollez assez fréquemment, vous finirez par consommer tous les ports disponibles, ce qui entraînera une erreur TCP 10048.

en général, la WCF tente d'éviter ce problème en regroupant les connexions et des choses comme ça. C'est généralement le cas pour les services internes qui ne passent pas par internet. Je ne suis pas sûr que l'une des liaisons wsHttp supporte la mise en commun des connexions, mais la liaison netTcp devrait. Je suppose que les canaux nommés n'exécutez pas ce problème. Je ne peux pas dire pour la reliure MSMQ.

Il y a deux solutions que vous pouvez utiliser pour contourner ce problème. Vous pouvez soit augmenter la plage de ports dynamiques, soit réduire la période de TIME_WAIT. La première est probablement la voie la plus sûre, mais si vous consommez un volume extrêmement élevé de sockets (ce qui n'est pas le cas pour votre scénario), réduire TIME_WAIT est une meilleure option (ou les deux ensemble).)

Modification de la plage de Port dynamique

  1. Ouvrez regedit.
  2. Open key HKLM\System\CurrentControlSet\Services\Tcpip\Parameters
  3. édite (ou crée en DWORD) la valeur MaxUserPort.
  4. fixe à un nombre plus élevé. (c'est à dire 65534)

changer le délai

  1. Ouvrez regedit.
  2. Open key HKLM\System\CurrentControlSet\Services\Tcpip\Parameters
  3. édite (ou crée en DWORD) le TcpTimedWaitDelay.
  4. Définir un nombre inférieur. La valeur est exprimée en secondes. (c'est à dire 60 pour 1 minute de retard)

l'Une des solutions ci-dessus devrait résoudre votre problème. Si elle persiste après avoir changé la gamme de port, je verrais essayer d'augmenter la période de votre sondage afin qu'il se passe moins fréquemment...cela vous donnera plus de marge de manœuvre pour travailler autour du délai d'attente. Je changerais le délai d'attente en dernier recours.

64
répondu jrista 2016-09-01 04:18:41

HttpClient, bien qu'il implémente IDisposable est un objet partagé, vous devez réduire le plus possible le nombre d'instances. Vous pouvez vous en tirer avec une seule instance pour toute la durée de vie de votre application plutôt qu'une pour chaque requête.

j'ai beaucoup écrit à ce sujet à http://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong /

5
répondu stimms 2016-09-01 19:09:15