Remember to maintain security and privacy. Do not share sensitive information. Procedimento.com.br may make mistakes. Verify important information. Termo de Responsabilidade

Como Resolver o Event ID 4227: Exaustão de Portas TCP/IP no Windows

Solução Técnica para Event ID 4227 em Desktops Windows

O Event ID 4227 ocorre devido à exaustão de portas dinâmicas TCP/IP em sistemas desktop Windows. Esta situação é comum quando diversos aplicativos mantêm conexões abertas ou criam novas conexões rapidamente.

Problemas típicos incluem falhas em navegadores, jogos, clientes torrent e ambientes de desenvolvimento. A seguir, orientações técnicas para resolver e prevenir essa condição.


Contexto Específico para Desktops

Cenários comuns:

  • Navegação intensa (múltiplas abas e extensões)
  • Aplicativos P2P (Torrent, VoIP)
  • Jogos online
  • Ambientes de desenvolvimento (Docker, VMs, IDEs)
  • Softwares de backup contínuo

Diferenças em relação a servidores:

  • Hardware mais limitado
  • Diversidade maior de aplicativos
  • Necessidade de equilíbrio entre performance e estabilidade

Soluções Técnicas

1. Ajuste Básico via Registro

Interface gráfica (Regedit):

  1. Abrir Regedit
  2. Navegar até:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
  3. Criar ou editar valores:

    • MaxUserPort (DWORD) = 65534
    • TcpTimedWaitDelay (DWORD) = 30 segundos

Via PowerShell (elevado):

Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "MaxUserPort" -Value 65534 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "TcpTimedWaitDelay" -Value 30 -Type DWord

2. Recomendações para Aplicativos Comuns

  • Navegadores: Limitar a 50-100 abas simultâneas.
  • Jogos: Ajustar configurações de rede em launchers (Steam, Epic).
  • Torrent: Reduzir número máximo de conexões (ex: qBittorrent → Opções → Conexão).

3. Otimizações Avançadas

Gamers:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]
"TcpAckFrequency"=dword:00000001
"TcpNoDelay"=dword:00000001
"EnableTCPChimney"=dword:00000001

Desenvolvedores:

  • Docker Desktop:
Set-NetTCPSetting -SettingName InternetCustom -CongestionProvider Cubic
  • WSL2:
Set-NetTCPSetting -SettingName DatacenterCustom -DynamicPortRangeStartPort 32768 -DynamicPortRangeNumberOfPorts 16384

4. Solução Rápida Emergencial

Script PowerShell para reset imediato:

Restart-Service -Name "Dnscache" -Force
Restart-Service -Name "WinHttpAutoProxySvc" -Force
ipconfig /flushdns
netsh int ip reset all

Monitoramento Contínuo

Widget com Rainmeter:

[TCPMonitor]
Measure=Plugin
Plugin=PerfMon
PerfMonObject="TCPv4"
PerfMonCounter="Connections Established"

[MeterText]
Meter=String
MeasureName=TCPMonitor
Text="Conexões TCP: %1"
FontSize=10
FontColor=255,255,255,255

Alerta de conexões elevadas (>1000 conexões ativas):

Add-Type -AssemblyName System.Windows.Forms
$tray = New-Object System.Windows.Forms.NotifyIcon
$tray.Icon = [System.Drawing.SystemIcons]::Information
$tray.Visible = $true

while ($true) {
    $conn = (Get-NetTCPConnection -State Established).Count
    if ($conn -gt 1000) {
        $tray.BalloonTipIcon = "Warning"
        $tray.BalloonTipText = "$conn conexões ativas!"
        $tray.ShowBalloonTip(5000)
    }
    Start-Sleep -Seconds 30
}

Casos Práticos Comuns

  • Antivírus (ex. Kaspersky): Configurar "Scan de conexões" para passivo.
  • Discord/Teams: Desativar aceleração de hardware nas configurações.
  • Windows Update: Limitar downloads simultâneos via GPO.

Recomendações Finais

  • Priorizar processos críticos:
Start-Process -FilePath "seu_app.exe" -PriorityClass High
  • Atualizar drivers de rede:
winget install --id Intel.Network.Drivers -e --force
  • Ajuste TCP global para usuários avançados:
netsh interface tcp set global autotuninglevel=restricted

Nota: Reinicializações periódicas ajudam a evitar acúmulo de conexões pendentes.

Script em Powershell para monitorar conexões TCP e rastrear alterações

<#
.SYNOPSIS
Monitora conexões TCP e rastreia alterações entre os intervalos de monitoramento.

.DESCRIÇÃO
Este script monitora conexões TCP ativas, rastreia alterações entre execuções e gera
um relatório CSV. Ele é executado por 4 iterações (40 segundos no total), a menos que seja interrompido com Ctrl+C.

.VERSÃO
1.1 - Correção de erros de caminho e melhorias na robustez
#>

# Configurações iniciais
$global:connectionData = [System.Collections.Generic.List[object]]::new()
$previousConnections = @{}
$monitorInterval = 10  # segundos
$maxIterations = 4
$currentIteration = 0
$reportFolder = [System.IO.Path]::Combine($env:USERPROFILE, "Documents", "TCP_Reports")
$csvPath = [System.IO.Path]::Combine($reportFolder, "TCP_Connection_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv")

# Verificar e criar diretório de relatórios se não existir
if (-not (Test-Path -Path $reportFolder)) {
    try {
        New-Item -ItemType Directory -Path $reportFolder -Force | Out-Null
        Write-Host "Diretório de relatórios criado: $reportFolder" -ForegroundColor Cyan
    }
    catch {
        Write-Warning "Falha ao criar diretório de relatórios. Usando diretório temporário."
        $reportFolder = [System.IO.Path]::GetTempPath()
        $csvPath = [System.IO.Path]::Combine($reportFolder, "TCP_Connection_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv")
    }
}

# Função para gerar relatório final com tratamento de erros
function Generate-FinalReport {
    [CmdletBinding()]
    param()

    begin {
        Write-Verbose "Preparando para gerar relatório final..."
    }

    process {
        try {
            if ($global:connectionData.Count -eq 0) {
                Write-Warning "Nenhum dado de conexão coletado para gerar relatório."
                return
            }

            # Criar cópia dos dados para manipulação
            $reportData = $global:connectionData.Clone()

            # Calcular estatísticas
            $summary = $reportData | 
                Group-Object PID | 
                ForEach-Object {
                    $max = ($_.Group | Measure-Object -Property Connections -Maximum).Maximum
                    $min = ($_.Group | Measure-Object -Property Connections -Minimum).Minimum
                    $avg = ($_.Group | Measure-Object -Property Connections -Average).Average

                    [PSCustomObject]@{
                        PID          = $_.Name
                        ProcessName  = $_.Group[0].ProcessName
                        Executable   = $_.Group[0].Executable
                        MaxConnections = $max
                        MinConnections = $min
                        AvgConnections = [math]::Round($avg, 1)
                        StatusChanges = ($_.Group.Change -join ", ")
                    }
                } | 
                Sort-Object -Property MaxConnections -Descending

            # Exportar para CSV com tratamento especial para caminhos longos
            try {
                $reportData | Export-Csv -Path $csvPath -NoTypeInformation -Force -Encoding UTF8
                Write-Host "Relatório CSV gerado com sucesso: " -NoNewline
                Write-Host $csvPath -ForegroundColor Cyan
            }
            catch {
                # Fallback para localização alternativa se houver erro
                $fallbackPath = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), "TCP_Connection_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv")
                $reportData | Export-Csv -Path $fallbackPath -NoTypeInformation -Force -Encoding UTF8
                Write-Host "Relatório CSV gerado em local alternativo: " -NoNewline
                Write-Host $fallbackPath -ForegroundColor Yellow
                $csvPath = $fallbackPath
            }

            # Exibir resumo no console
            Write-Host "`nResumo do Monitoramento" -ForegroundColor Green
            Write-Host "======================"
            Write-Host "Período: $($reportData[0].Timestamp) até $($reportData[-1].Timestamp)"
            Write-Host "Total de amostras: $($reportData.Count)"
            Write-Host "Processos únicos monitorados: $($summary.Count)`n"

            $summary | Format-Table -AutoSize -Property `
                @{Name="PID"; Expression={$_.PID}; Alignment="Right"},
                @{Name="Processo"; Expression={$_.ProcessName}},
                @{Name="Máx"; Expression={$_.MaxConnections}; Alignment="Right"},
                @{Name="Mín"; Expression={$_.MinConnections}; Alignment="Right"},
                @{Name="Méd"; Expression={$_.AvgConnections}; Alignment="Right"}

            # Top 3 consumidores
            $topConsumers = $summary | Sort-Object -Property MaxConnections -Descending | Select-Object -First 3
            if ($topConsumers) {
                Write-Host "`nTop 3 Consumidores de Conexões:" -ForegroundColor Yellow
                $topConsumers | ForEach-Object {
                    Write-Host ("- {0} (PID {1}):" -f $_.ProcessName, $_.PID)
                    Write-Host ("  Máx: {0} conexões | Média: {1} conexões" -f $_.MaxConnections, $_.AvgConnections)
                }
            }

            # Sugestões baseadas nos dados
            $highConsumers = $summary | Where-Object { $_.MaxConnections -gt 100 }
            if ($highConsumers) {
                Write-Host "`nRecomendações:" -ForegroundColor Magenta
                $highConsumers | ForEach-Object {
                    Write-Host ("- Processo {0} (PID {1}) possui pico de {2} conexões." -f 
                        $_.ProcessName, $_.PID, $_.MaxConnections)

                    if ($_.ProcessName -match "chrome|edge|firefox") {
                        Write-Host "  * Considere reduzir abas/extensões no navegador" -ForegroundColor DarkYellow
                    }
                    elseif ($_.ProcessName -match "torrent|qbittorrent|utorrent") {
                        Write-Host "  * Ajuste limites de conexão no cliente P2P" -ForegroundColor DarkYellow
                    }
                }
            }
        }
        catch {
            Write-Error "Erro durante geração de relatório: $_"
            Write-Warning "Dados brutos disponíveis na variável `$global:connectionData"
        }
    }

    end {
        Write-Verbose "Geração de relatório concluída"
    }
}

# Main monitoring loop
try {
    [System.Console]::TreatControlCAsInput = $true

    while ($currentIteration -lt $maxIterations) {
        $currentConnections = Get-ProcessConnections

        # Update tracking
        $currentResults = Update-ConnectionTracking -currentConnections $currentConnections
        $global:connectionData += $currentResults

        # Store current state for next comparison
        $previousConnections = @{}
        $currentConnections | ForEach-Object {
            $previousConnections[$_.PID] = @{
                Connections = $_.Connections
                ProcessName = $_.ProcessName
                Executable  = $_.Executable
            }
        }

        Display-ConnectionSummary -connections $currentResults

        $currentIteration++
        if ($currentIteration -lt $maxIterations) {
            Write-Host "`nNext update in $monitorInterval seconds (Press Ctrl+C to stop)..." -ForegroundColor DarkGray

            # Check for Ctrl+C during wait
            $startTime = Get-Date
            while (((Get-Date) - $startTime).TotalSeconds -lt $monitorInterval) {
                if ([System.Console]::KeyAvailable) {
                    $key = [System.Console]::ReadKey($true)
                    if (($key.Modifiers -band [System.ConsoleModifiers]::Control) -and ($key.Key -eq "C")) {
                        throw [System.OperationCanceledException]::new("Monitoring interrupted by user")
                    }
                }
                Start-Sleep -Milliseconds 200
            }
        }
    }

    # Na interrupção ou conclusão:
    Generate-FinalReport -ErrorAction Continue
}
catch [System.OperationCanceledException] {
    Invoke-SignalHandler
}
catch {
    Write-Warning "Monitoramento interrompido: $_"
    Generate-FinalReport -ErrorAction Continue    
}
finally {
    [System.Console]::TreatControlCAsInput = $false
    $host.UI.RawUI.BackgroundColor = $originalBackgroundColor
    $host.UI.RawUI.ForegroundColor = $originalForegroundColor
}

To share Download PDF

Gostou do artigo? Deixe sua avaliação!
Sua opinião é muito importante para nós. Clique em um dos botões abaixo para nos dizer o que achou deste conteúdo.