2009-08-27 35 views
35

Tengo un servicio WCF y una aplicación web. La aplicación web realiza llamadas a este servicio WCF de manera continua a.k. un sondeo. En nuestro entorno de producción, recibo este error muy raramente. Dado que, esta es una actividad interna que los usuarios no conocían cuando se lanzó este error.WCF: System.Net.SocketException - Normalmente solo se permite un uso de cada dirección de socket (protocolo/dirección de red/puerto)

No se pudo conectar con http://localhost/QAService/Service.svc. Código de error TCP 10048: solo un uso de cada dirección de socket (protocolo/dirección de red/puerto) es normalmente permitido 127.0.0.1:80. ---> System.Net.WebException: No se puede conectar con el servidor remoto ---> System.Net.Sockets.SocketException: Sólo un uso de cada dirección de socket (protocolo/dirección de red/puerto) es normalmente permitido 127.0.0.1:80

Tengo problemas para reproducir este comportamiento en nuestro entorno dev/qa. Me he asegurado de que la conexión del cliente esté cerrada en un bloque try..catch..finally. Todavía no entiendo qué está causando este problema ... ¿alguien al tanto de esto?

Nota: He visto esto SO question, pero parece que no responde mi problema, por lo que no se repiten las preguntas.

+0

¿Eso es porque el servicio web está utilizando el puerto 80, que está en uso por IIS? ¿Qué puerto usa tu servicio en producción? ¿En qué puerto está configurado IIS en producción? – shahkalpesh

+0

Es el mismo 80 para ambas aplicaciones. El servicio WCF se configura como un directorio virtual dentro de la raíz en la que está alojado el sitio. Entonces, ¿está diciendo que podría haber ocasionalmente un conflicto entre la solicitud de la página web y una solicitud al servicio de la página web que intenta usar el mismo puerto? – asyncwait

+0

He encontrado una situación similar. Planear el uso de la función para compartir puertos net tcp en el servicio wcf. http://msdn.microsoft.com/en-us/library/ms734772.aspx Por favor, hágamelo saber si esto funciona –

Respuesta

59

Está sobrecargando la pila TCP/IP. Windows (y creo que todas las pilas de tomas en realidad) tienen una limitación en el número de tomas que se pueden abrir en secuencia rápida debido a cómo se cierran las tomas bajo operación normal. Cada vez que se cierra un socket, ingresa al estado TIME_WAIT durante un tiempo determinado (240 segundos IIRC). Cada vez que sondea, un socket se consume fuera del rango dinámico predeterminado (creo que son alrededor de 5000 puertos dinámicos justo por encima de 1024), y cada vez que finaliza ese sondeo, ese socket en particular entra en TIME_WAIT. Si realiza una encuesta con la frecuencia suficiente, con el tiempo consumirá todos los puertos disponibles, lo que dará como resultado el error TCP 10048.

En general, WCF intenta evitar este problema agrupando conexiones y cosas por el estilo. Este suele ser el caso de los servicios internos que no se transmiten por Internet. No estoy seguro de si alguno de los enlaces wsHttp admite la agrupación de conexiones, pero el enlace netTcp debería. Supongo que las tuberías con nombre no se topan con este problema. No podría decir para el enlace de MSMQ.

Existen dos soluciones que puede utilizar para solucionar este problema. Puede aumentar el rango del puerto dinámico o reducir el período de TIME_WAIT. La primera es probablemente la ruta más segura, pero si consume un volumen extremadamente alto de sockets (que no suena como en su caso), reducir TIME_WAIT es una mejor opción (o ambas juntas).

Cambio del rango dinámico de puertos

  1. Abrir regedit.
  2. Tecla de abrir HKLM \ System \ CurrentControlSet \ Services \ Tcpip \ Parámetros
  3. Editar (o crear como DWORD) el valor MaxUserPort.
  4. Establézcalo en un número superior. (es decir.65534)

Cambio del retardo TIME_WAIT

  1. regedit Abrir.
  2. Tecla de abrir HKLM \ System \ CurrentControlSet \ Services \ Tcpip \ Parámetros
  3. Editar (o crear como DWORD) el TcpTimedWaitDelay.
  4. Configúrelo en un número menor. El valor está en segundos. (es decir, 60 para un retraso de 1 minuto)

Una de las soluciones anteriores debería solucionar su problema. Si persiste después de cambiar el rango del puerto, vería intentar aumentar el período de su votación para que ocurra con menos frecuencia ... eso le dará más libertad de acción para evitar el retraso de espera. Cambiaría el tiempo de demora de espera como último recurso.

+0

Uhm ... este enlace http://msdn.microsoft.com/en-us/library/aa560610 (v = bts.20) .aspx deletrea el parámetro TCPTimeWaitDelay de manera diferente. Lo deletrea TcpTimedWaitDelay. ¿Cómo puedo obtener la confirmación de cuál es? Más información de technet: http://technet.microsoft.com/en-us/library/cc938217.aspx – Jaans

+0

¿Es la carcasa adecuada TcpTimeWaitDelay? Si es así, arreglaré la respuesta. – jrista

+1

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

3

HttpClient, aunque implementa IDisposable es un objeto compartido, debe reducir el número de instancias tanto como sea posible. Puede salirse con la suya teniendo solo una instancia durante toda la vida de su aplicación en lugar de una para cada solicitud.

Escribí sobre ello bastante ampliamente en http://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

Cuestiones relacionadas