![Socat não fecha a conexão TCP](https://rvso.com/image/1490203/Socat%20n%C3%A3o%20fecha%20a%20conex%C3%A3o%20TCP.png)
Eu uso socat 1.7.3.1-r0
e executo o seguinte comando em um 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
escutará os clientes e criará uma comunicação bidirecional, passando dados da porta serial virtual /dev/ttyFOOBAR
para o cliente e vice-versa por TCP. Assim que o cliente se desconectar, socat
ele deverá sair.
Quando tal conexão é estabelecida, o socat registra o seguinte:
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
comando no 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
O problema é que quando eu desconecto o cliente (desligando-o), a conexão tcp ainda está estabelecida e nenhum registro adicional vem do socat. ss
ainda mostra a conexão como ESTAB. Alguma idéia do porquê? Quando eu conecto novamente o cliente aparece o seguinte nos logs:
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
Mas por que isso acontece ao conectar em vez de desconectar?
Responder1
Quando você desliga o cliente, ele não tem oportunidade de dizer ao outro lado que está indo embora. A única maneira de saber que o par desapareceu é tentar enviar algo para ele e perceber que ele não responde.
Se for um requisito em seu aplicativo que um peer morto seja detectado, você terá que implementar a detecção de peer morto. Você pode fazer isso ativando a keepalive
opção em socat
, mas ainda pode levar várias horas para detectar um par morto. Você também pode fazer isso enviando algo periodicamente - o tempo de envio expirará se o par estiver morto, acionando a detecção. Se o outro lado deveria estar enviando dados para você, você poderá abortar se não tiver recebido os dados esperados (talvez com socat
o sinalizador ' -T
).