![Socat schließt die TCP-Verbindung nicht](https://rvso.com/image/1490203/Socat%20schlie%C3%9Ft%20die%20TCP-Verbindung%20nicht.png)
Ich verwende socat 1.7.3.1-r0
und führe den folgenden Befehl auf einem alpine 3.3
Linux-Server aus:
socat -d -d -d PTY,link=/dev/ttyFOOBAR,echo=0,raw,unlink-close=0 TCP-LISTEN:7000,forever,reuseaddr
Socat
wartet auf Clients und erstellt eine bidirektionale Kommunikation, indem Daten /dev/ttyFOOBAR
über TCP vom virtuellen seriellen Port an den Client und wieder zurück weitergeleitet werden. Sobald der Client die Verbindung trennt, socat
sollte er beendet werden.
Wenn eine solche Verbindung hergestellt wird, protokolliert socat Folgendes:
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
Befehl auf dem Server druckt:
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp ESTAB 0 0 172.20.0.2:7000 CLIENT_IP:PORT
Das Problem ist, dass, wenn ich den Client trenne (indem ich ihn ausschalte), die TCP-Verbindung immer noch besteht und keine zusätzlichen Protokolle von Socat kommen. ss
zeigt die Verbindung immer noch als ESTAB an. Irgendwelche Ideen, warum? Wenn ich den Client erneut verbinde, erscheint Folgendes in den Protokollen:
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
Aber warum geschieht dies beim Verbinden und nicht beim Trennen?
Antwort1
Wenn Sie den Client ausschalten, hat er keine Gelegenheit, der anderen Seite mitzuteilen, dass er weggeht. Die einzige Möglichkeit, festzustellen, dass der Peer weg ist, besteht darin, ihm etwas zu senden und festzustellen, dass er nicht antwortet.
Wenn Ihre Anwendung die Erkennung eines toten Peers erfordert, müssen Sie die Erkennung toter Peers implementieren. Sie können dies tun, indem Sie die keepalive
Option in aktivieren socat
, aber es kann trotzdem mehrere Stunden dauern, bis ein toter Peer erkannt wird. Sie können dies auch tun, indem Sie in regelmäßigen Abständen etwas senden – das Senden wird unterbrochen, wenn der Peer tot ist, was die Erkennung auslöst. Wenn die andere Seite Ihnen Daten senden soll, können Sie abbrechen, wenn Sie die erwarteten Daten nicht erhalten haben (möglicherweise mit dem Flag socat
von -T
).