GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo usar la opción SO_KEEPALIVE correctamente para detectar que el cliente en el otro extremo está inactivo?

Para modificar el número de sondeos o los intervalos de sondeo, escriba valores en el sistema de archivos /proc como

 echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time
 echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl
 echo 20 > /proc/sys/net/ipv4/tcp_keepalive_probes

Tenga en cuenta que estos valores son globales para todos los sockets habilitados para keepalive en el sistema. También puede anular esta configuración por socket cuando configura setsockopt, consulte la sección 4.2 del documento que vinculó.

No puede "verificar" el estado del socket desde el espacio de usuario con keepalive. En cambio, el kernel es simplemente más agresivo al obligar al extremo remoto a reconocer los paquetes y determinar si el socket se ha estropeado. Cuando intente escribir en el socket, obtendrá un SIGPIPE si keepalive ha determinado que el extremo remoto está inactivo.


Obtendrá el mismo resultado si habilita SO_KEEPALIVE, como si no habilita SO_KEEPALIVE; por lo general, encontrará el socket listo y obtendrá un error cuando lo lea.

Puede configurar el tiempo de espera de actividad por socket en Linux (esta puede ser una característica específica de Linux). Recomendaría esto en lugar de cambiar la configuración de todo el sistema. Consulte la página man de tcp para obtener más información.

Finalmente, si su cliente es un navegador web, es muy probable que cierre el socket con bastante rapidez de todos modos; la mayoría de ellos solo mantendrán abiertas las conexiones keepalive (HTTP 1.1) durante un tiempo relativamente corto (30 segundos, 1 minuto, etc.). Por supuesto, si la máquina cliente ha desaparecido o la red no funciona (que es lo que SO_KEEPALIVE es realmente útil para detectar), entonces no podrá cerrar activamente el socket.


Como ya se discutió, SO_KEEPALIVE hace que el núcleo sea más agresivo en la verificación continua de la conexión, incluso cuando no está haciendo nada, pero no cambiar o mejorar la forma en que se le entrega la información. Lo sabrá cuando intente hacer algo (por ejemplo, "escribir"), y lo sabrá de inmediato, ya que el kernel ahora solo informa el estado de un indicador establecido previamente, en lugar de tener que esperar unos minutos. segundos (o mucho más en algunos casos) para que falle la actividad de la red. Se seguirá utilizando exactamente la misma lógica de código que tenía para manejar la condición "el otro lado se fue inesperadamente"; lo que cambia es el tiempo (no el método).

Prácticamente todos los programas de sockets "prácticos" de alguna manera proporcionan non -bloqueando el acceso a los sockets durante la fase de datos (quizás con select()/poll(), o quizás con fcntl()/O_NONBLOCK/EINPROGRESS&EWOULDBLOCK, o si su kernel lo admite, quizás con MSG_DONTWAIT). Suponiendo que esto ya se haya hecho por otras razones, es trivial (a veces no requiere ningún código) descubrir además de inmediato si se ha interrumpido una conexión. Pero si la fase de datos no ya proporciona de alguna manera acceso sin bloqueo a los enchufes, no se enterará de que la conexión se cae hasta la próxima vez que intente hacer algo.

(Una conexión de socket TCP sin algún tipo de comportamiento de no bloqueo durante la fase de datos es notoriamente frágil, ya que si el paquete incorrecto encuentra un problema de red, es muy fácil que el programa se "bloquee" indefinidamente, y no hay mucho que usted puede hacer al respecto.)


Linux
  1. Cómo usar el comando grep de Linux

  2. Cómo usar el comando de historial en Linux

  3. ¿Cómo usar el comando basename?

  4. ¿Cómo agregar una nueva línea al final de un archivo?

  5. LINUX:cómo detectar que la carga del archivo ftp ha terminado

Cómo usar el comando superior en Linux

Cómo usar el comando ping de Linux

Cómo usar el comando nmap

Cómo usar el comando fd en el sistema Linux

¿Cómo usar el comando wget en Linux?

¿Cómo usar el comando xargs en Linux?