2009-08-27 1 views
35

Ho un servizio WCF e un'applicazione Web. L'applicazione Web effettua chiamate a questo servizio WCF in modo continuo a.k.un sondaggio. 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.WCF: System.Net.SocketException - Solo un utilizzo di ciascun indirizzo socket (protocollo/indirizzo di rete/porta) è normalmente consentito

Impossibile connettersi a http://localhost/QAService/Service.svc. Codice errore TCP 10048: solo un utilizzo di ciascun indirizzo socket (protocollo/indirizzo di rete/porta) è normalmente consentito 127.0.0.1:80. ---> System.Net.WebException: impossibile 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

Ho 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?

: ho visto questo SO question, ma non sembra che risponda al mio problema, quindi non si tratta di domande ripetute.

+0

è che, poiché il servizio Web utilizza la porta 80, che è in uso da parte di IIS? Quale porta utilizza il tuo servizio in produzione? Quale porta, IIS è configurato in produzione? – shahkalpesh

+0

È lo stesso 80 per entrambe le applicazioni. Il servizio WCF è configurato come una directory virtuale all'interno della radice in cui è ospitato il sito. Quindi, stai dicendo che potrebbe esserci occasionalmente un conflitto tra la richiesta di entrambe le pagine Web e una richiesta di servizio da una pagina Web che tenta di utilizzare la stessa porta? – asyncwait

+0

Ho riscontrato una situazione simile. Pianificazione per utilizzare la funzionalità di condivisione porta tcp in rete nel servizio wcf. http://msdn.microsoft.com/en-us/library/ms734772.aspx Per favore fatemi sapere se questo funziona –

risposta

59

Si sta 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 esegui un sondaggio abbastanza frequente, finirai per utilizzare tutte le porte disponibili, con conseguente errore TCP 10048.

Generalmente, WCF tenta di evitare questo problema collegando le 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 è possibile utilizzare per ovviare a questo problema. È possibile 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 tuo scenario), ridurre TIME_WAIT è un'opzione migliore (o entrambe).

Modifica dell'intervallo di porte dinamiche

  1. Aperto regedit.
  2. Chiave aperta HKLM \ System \ CurrentControlSet \ Services \ Tcpip \ Parameters
  3. Modificare (o creare come DWORD) il valore MaxUserPort.
  4. Impostarlo su un numero più alto. (Cioè65534)

Cambiare il ritardo TIME_WAIT

  1. Aprire regedit.
  2. Chiave aperta HKLM \ System \ CurrentControlSet \ Services \ Tcpip \ Parameters
  3. Modificare (o creare come DWORD) il TcpTimedWaitDelay.
  4. Impostarlo su un numero inferiore. Il valore è in secondi. (vale a dire 60 per 1 minuto di ritardo)

Una delle soluzioni di cui sopra dovrebbe risolvere il 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.

+0

Uhm ... questo link http://msdn.microsoft.com/en-us/library/aa560610 (v = bts.20) .aspx scrive diversamente il parametro TCPTimeWaitDelay. Si scrive TcpTimedWaitDelay. Come posso ottenere conferma quale è? Ulteriori informazioni da technet: http://technet.microsoft.com/en-us/library/cc938217.aspx – Jaans

+0

È l'involucro corretto TcpTimeWaitDelay? Se è così, correggerò la risposta. – jrista

+1

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters \ TcpTimedWaitDelay – granadaCoder

3

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

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