Only one usage of each socket address (protocol/network address/port) is normally permitted

Problema

A aplicação apresenta erros de conexão com o banco de dados, e em alguns casos, pode resultar na interrupção do Pool de Aplicativos do IIS, devido a erros na inicialização da aplicação.

Nessa situação, a mensagem a seguir poderá ser observada nos logs de arquivo de texto:

System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted

A mensagem também pode ser apresentada em português:

System.Net.Sockets.SocketException: Normalmente é permitida apenas uma utilização de cada endereço de soquete (protocolo/endereço de rede/porta)

Causa

De forma resumida, este erro ocorre quando o Windows não tem mais portas dinâmicas disponíveis para estabelecer uma nova comunicação TCP/IP. Neste caso, uma comunicação de rede entre servidor de aplicação e de banco de dados.

Conexão em estado TIME_WAIT

Embora as conexões com o banco de dados estejam sendo encerradas corretamente pela aplicação, a comunicação entre os dois computadores não é finalizada imeditamente. Ela continua estabelecida, porém em estado TIME_WAIT.

As conexões em estado TIME_WAIT podem ser verificadas com o seguinte comando:

netstat -a

image

Mesmo encerrando a aplicação no IIS, as conexões continuarão em estado TIME_WAIT, pois quem gerencia isso é o Sistema Operacional, e não a aplicação.

Por padrão, o Windows aguarda entre 2 e 4 minutos para encerrar conexões no estado TIME_WAIT.

Intervalo de portas dinâmicas

Ao tentar estabelecer uma nova conexão TCP/IP (neste caso com o servidor de banco de dados), o Window utiliza uma porta dinâmica disponível. Porém o número de portas que podem ser utilizadas nesta operação é limitado.

O intervalo de portas dinâmicas definido para o protocolo TCP pode ser verificado com a seguinte linha de comando:

netsh int ipv4 show dynamicport tcp

image

Esgotamento de Portas

Uma porta dinâmica usada em uma conexão TCP/IP entre dois computadores não poderá ser reutilizada enquanto a conexão estiver em estado TIME_WAIT.

Eventualmente, com o acúmulo de conexões neste estado, ocorrerá o esgotamento de portas dinâmicas, o que levará a ocorrência dos erros.

Solução

Existem 3 soluções que podem ser usadas combinadas ou individualmente para solucionar o problema:

Utilizar Pooling de Conexões

Usando o Pool de Conexões, você terá um número menor de novas conxões sendo abertas, e consequentemente, vai ser mais difícil esgotar o número de portas dinâmicas.

Mais informações neste tópico: Pooling de Conexões

Reduzir o tempo de TIME_WAIT

Reduzindo o tempo de TIME_WAIT, a porta bloqueada será liberada mais cedo, e consequentemente, vai ser mais difícil esgotar o número de portas dinâmicas.

Para definir TcpTimedWaitDelay (tempo limite do TIME_WAIT):

  1. Use o comando regedit para acessar a subchave do registro HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ Services\TCPIP\Parameters .

  2. Crie um novo valor REG_DWORD chamado “TcpTimedWaitDelay”, e defina o valor como 30 (segundos).

  3. Crie um novo valor REG_DWORD chamado “StrictTimeWaitSeqCheck”, e defina o valor como 1.

  4. Reinicie o sistema.

O parâmetro "TcpTimedWaitDelay" deve ser definido para garantir que o sistema operacional, vai aplicar o valor de "StrictTimeWaitSeqCheck".

Aumentar o intervalo de portas dinâmicas

Aumentando o número de portas dinâmicas, será possível ter mais conexões simultâneas em estado TIME_WAIT.

Para definir MaxUserPort (intervalo de portas dinâmicas):

  1. Use o comando regedit para acessar a subchave do registro HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ Services\TCPIP\Parameters.

  2. Crie um novo valor REG_DWORD chamado “MaxUserPort”.

  3. Defina esse valor como 65534 (máximo).

  4. Reinicie o sistema.


Mais informações aqui: Only one usage of each socket address (protocol/network address/port) is normally permitted | Microsoft Learn