WCF: System.Net.SocketException – È consentito un solo utilizzo di ciascun indirizzo socket (protocollo / indirizzo di rete / porta)

Ho un servizio WCF e un’applicazione Web. L’applicazione Web effettua chiamate a questo servizio WCF in modo continuo, come il polling. Nel nostro ambiente di produzione, ricevo questo errore molto raramente. Poiché, questa è un’attività interna di cui gli utenti non erano a conoscenza quando viene generato questo errore.

Imansible connettersi a http: //localhost/QAService/Service.svc . TCP error code 10048: Solitamente un uso di ciascun indirizzo socket (protocollo / indirizzo di rete / porta) è normalmente consentito 127.0.0.1:80. —> System.Net.WebException: imansible connettersi al server remoto —> System.Net.Sockets.SocketException: solo un utilizzo di ciascun indirizzo socket (protocollo / indirizzo di rete / porta) è normalmente consentito 127.0.0.1 : 80

Sto avendo problemi nel riprodurre questo comportamento nel nostro ambiente dev / qa. Mi sono assicurato che la connessione client fosse chiusa in un try..catch..finally block. Ancora non capisco cosa sta causando questo problema .. qualcuno ne è a conoscenza?

Nota : ho esaminato questa domanda SO , ma non sembra che risponda al mio problema, quindi non si tratta di domande ripetute.

Stai sovraccaricando lo stack TCP / IP. Windows (e penso che tutti gli stack di socket in realtà) abbiano una limitazione sul numero di socket che possono essere aperti in rapida sequenza a causa del modo in cui i socket vengono chiusi durante il normale funzionamento. Ogni volta che una presa è chiusa, entra nello stato TIME_WAIT per un certo tempo (240 secondi IIRC). Ogni volta che si esegue il polling, un socket viene utilizzato al di fuori dell’intervallo dinamico predefinito (penso che sia circa 5000 porte dinamiche appena superiori a 1024) e ogni volta che termina il sondaggio, quel particolare socket entra in TIME_WAIT. Se si esegue il polling abbastanza frequentemente, alla fine si consumeranno tutte le porte disponibili, con conseguente errore TCP 10048.

Generalmente, WCF tenta di evitare questo problema mettendo in comune connessioni e cose del genere. Questo è solitamente il caso con servizi interni che non stanno andando su Internet. Non sono sicuro che nessuno dei collegamenti wsHttp supporti il ​​pool di connessioni, ma dovrebbe essere il binding netTcp. Supporrei che named pipe non si imbatta in questo problema. Non potrei dire per l’associazione MSMQ.

Esistono due soluzioni che è ansible utilizzare per ovviare a questo problema. È ansible aumentare l’intervallo di porte dinamico o ridurre il periodo di TIME_WAIT. Il primo è probabilmente il percorso più sicuro, ma se stai consumando un volume estremamente elevato di socket (che non sembra il caso del tuo scenario), ridurre TIME_WAIT è un’opzione migliore (o entrambe insieme).

Modifica della gamma di porte dinamiche

  1. Apri regedit.
  2. Chiave aperta HKLM \ System \ CurrentControlSet \ Services \ Tcpip \ Parameters
  3. Modifica (o crea come DWORD) il valore MaxUserPort.
  4. Impostalo su un numero più alto. (cioè 65534)

Modifica del ritardo TIME_WAIT

  1. Apri regedit.
  2. Chiave aperta HKLM \ System \ CurrentControlSet \ Services \ Tcpip \ Parameters
  3. Modifica (o crea come DWORD) il TcpTimedWaitDelay.
  4. Impostalo su un numero inferiore. Il valore è in secondi. (cioè 60 per 1 minuto di ritardo)

Una delle soluzioni di cui sopra dovrebbe risolvere il tuo problema. Se persiste dopo aver cambiato l’intervallo di porte, vedrei provare ad aumentare il periodo del sondaggio in modo che avvenga meno frequentemente … che ti darà più margine di manovra per aggirare il ritardo di attesa del tempo. Vorrei cambiare il tempo di attesa come ultima risorsa.

HttpClient, anche se implementa IDisposable è un object condiviso, dovresti ridurre il più ansible il numero di istanze. Puoi fare a meno di avere un’istanza per l’intera durata della tua applicazione anziché di una per ogni richiesta.

Ne ho scritto abbastanza estesamente su http://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/