한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

Libro blanco del lag en juegos › L8 Sockets y protocolos

Keepalive con valor predeterminado de 2 horas TCP keepalive defaults

ID de la causa sk-keepalive · Responsable principal Desarrollo de servidor (Equipo de desarrollo) · También Desarrollo de cliente (Equipo de desarrollo), Infraestructura de servidores (Equipo de infraestructura)

Abrir la ficha interactiva con gráficos y simulaciones →

Si el otro extremo desaparece sin enviar una señal de cierre, TCP tarda mucho en detectarlo. El keepalive (la función de TCP que comprueba si una conexión inactiva sigue viva) viene desactivado por defecto y, aunque se active, no empieza a comprobar hasta que la conexión lleva 2 horas inactiva.

Por qué El cliente desaparece sin señal de cierre porque se apaga o se corta su conexión → Efecto El servidor da la conexión por viva (keepalive predeterminado: 7,200 segundos; si había datos pendientes de envío, unos 15 minutos hasta abandonar la retransmisión) → En pantalla Queda un personaje fantasma y, al reconectar, aparece el error “Ya estás conectado”

Síntomas
No conecta / carga infinita, Entidades invisibles / fantasma
Factores
Pérdida de paquetes
A quién afecta
Solo yo
Cuándo
Tras un rato inactivo, Al conectar o tras un mantenimiento
Responsable
Responsable principal Desarrollo de servidor (Equipo de desarrollo) · También Desarrollo de cliente (Equipo de desarrollo), Infraestructura de servidores (Equipo de infraestructura)
Tareas (Equipo de desarrollo)
Servidor: responder a los heartbeats y cerrar la conexión por su cuenta si no los recibe durante cierto tiempo (ajustar TCP_KEEPIDLE y TCP_USER_TIMEOUT), al reconectar, reemplazar la sesión anterior mediante el token de sesión y retomarla. Cliente: enviar heartbeats a nivel de juego cada pocos segundos o decenas de segundos (como mucho, la mitad del timeout por inactividad más corto), reconectar automáticamente si se corta.
Tareas (Equipo de infraestructura)
Bajar los valores predeterminados del kernel (tcp_keepalive_time, entre otros) para los sockets cuyo código no los fija (solo se aplica a los sockets con SO_KEEPALIVE activado).
Cifras de referencia
Por defecto, Linux empieza a comprobar tras 7,200 segundos de inactividad, envía 9 sondas a intervalos de 75 segundos y, si no recibe respuesta, corta la conexión. En total, unas 2 horas y 11 minutos. Windows también espera por defecto 2 horas de inactividad antes de empezar a comprobar.
En el gráfico
Alto solo en algunos · Tiempo desde la última recepción por conexión
Dónde mirar
lastrcv (ms desde la última recepción) y el temporizador de keepalive (timer:(keepalive,…)) por conexión con ss -tnoi, cruzados con los rechazos “Ya estás conectado” del servidor del juego
Se confirma si
Quedan conexiones ESTABLISHED con un lastrcv de minutos u horas, y la reconexión de esa cuenta se rechaza con “Ya estás conectado”
Se descarta si
Si no hay conexiones inactivas desde hace mucho y aun así sale “Ya estás conectado”, apunta al código de limpieza de sesiones del servidor del juego
Se verifica con
Con herramientas de infraestructura (no hace falta código del juego)

Fuentes

  1. tcp(7) — Linux manual page Linux man-pages
    Tras 7,200 segundos de inactividad, 9 sondas a intervalos de 75 segundos (unos 11 minutos más); solo se aplica a los sockets con SO_KEEPALIVE activado; TCP_KEEPIDLE y TCP_USER_TIMEOUT
  2. RFC 9293: Transmission Control Protocol (TCP) IETF
    El keepalive debe venir desactivado por defecto, y el intervalo de inactividad predeterminado debe ser de 2 horas o más
  3. SO_KEEPALIVE socket option Microsoft
    Timeout predeterminado del keepalive TCP de Windows: 2 horas
  4. ss(8) — Linux manual page iproute2
    lastrcv (ms desde la última recepción) de -i y timer:(keepalive,…) de -o

Ver también

Misma capa: L8 Sockets y protocolos

Causas de otras capas con el mismo síntoma (No conecta / carga infinita)

Ver la ficha interactiva con gráficos y simulaciones