![Socat no cierra la conexión TCP](https://rvso.com/image/1490203/Socat%20no%20cierra%20la%20conexi%C3%B3n%20TCP.png)
Utilizo socat 1.7.3.1-r0
y ejecuto el siguiente comando en un alpine 3.3
servidor Linux:
socat -d -d -d PTY,link=/dev/ttyFOOBAR,echo=0,raw,unlink-close=0 TCP-LISTEN:7000,forever,reuseaddr
Socat
escuchará a los clientes y creará una comunicación bidireccional pasando datos desde el puerto serie virtual /dev/ttyFOOBAR
al cliente y viceversa a través de TCP. Una vez que el cliente se desconecte, socat
debe salir.
Cuando se establece dicha conexión, socat registra lo siguiente:
I socat by Gerhard Rieger - see www.dest-unreach.org I This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. (http://www.openssl.org/) I This product includes software written by Tim Hudson ([email protected]) I setting option "symbolic-link" to "/dev/ttyFOOBAR" I setting option "echo" to 0 I setting option "raw" I setting option "unlink-close" to 0 I openpty({5}, {6}, {"/dev/pts/3"},,) -> 0 N PTY is /dev/pts/3 I setting option "forever" to 1 I setting option "so-reuseaddr" to 1 I socket(2, 1, 6) -> 7 I starting accept loop N listening on AF=2 0.0.0.0:7000 I accept(7, {2, AF=2 CLIENT_IP:PORT}, 16) -> 8 N accepting connection from AF=2 CLIENT_IP:PORT on AF=2 172.20.0.2:7000 I permitting connection from AF=2 CLIENT_IP:PORT I close(7) I resolved and opened all sock addresses N starting data transfer loop with FDs [5,5] and [8,8]
ss
El comando en el servidor imprime:
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp ESTAB 0 0 172.20.0.2:7000 CLIENT_IP:PORT
El problema es que cuando desconecto el cliente (apagándolo), la conexión TCP aún está establecida y no proviene ningún registro adicional de socat. ss
todavía muestra la conexión como ESTAB. ¿Alguna idea de por qué? Cuando vuelvo a conectar el cliente, aparece lo siguiente en los registros:
W read(8, 0x7fa8f48c4020, 8192): Connection reset by peer
N socket 2 to socket 1 is in error
N socket 2 (fd 8) is at EOF
I poll timed out (no data within 0.500000 seconds)
I close(5)
I shutdown(8, 2)
I shutdown(8, 2): Socket not connected
N exiting with status 0
Pero, ¿por qué sucede esto al conectar en lugar de al desconectarse?
Respuesta1
Cuando cierras al cliente, no tiene oportunidad de decirle a la otra parte que va a desaparecer. La única forma de saber que el par se ha ido es intentar enviarle algo y notar que no responde.
Si es un requisito en su aplicación que se detecte un par muerto, tendrá que implementar la detección de pares muertos. Puede hacer esto habilitando la keepalive
opción en socat
, pero aún puede tomar varias horas detectar un par muerto. También puede hacer esto enviando algo periódicamente; el envío expirará si el par está muerto, lo que activará la detección. Si se supone que la otra parte le está enviando datos, puede cancelar si no ha recibido los datos que espera (quizás con socat
la -T
bandera).