Я использую socat 1.7.3.1-r0 и запускаю следующую команду на Linux-сервере Alpine alpine 3.3 :

socat -d -d -d PTY,link=/dev/ttyFOOBAR,echo=0,raw,unlink-close=0 TCP-LISTEN:7000,forever,reuseaddr

Socat будет прослушивать клиентов и создавать двунаправленную связь, передавая данные из виртуального последовательного порта /dev/ttyFOOBAR клиенту и обратно через TCP. Как только клиент отключается, socat должен выйти.

Когда такое соединение установлено, socat регистрирует следующее:

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 (tjh@cryptsoft.com)
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 на сервере печатает:

Netid  State      Recv-Q Send-Q Local Address:Port                 Peer Address:Port                
tcp    ESTAB      0      0      172.20.0.2:7000                 CLIENT_IP:PORT

Проблема в том, что когда я отключаю клиента (отключая его), соединение tcp все еще установлено, и от socat не поступает дополнительная регистрация. ss прежнему показывает соединение как ESTAB. Есть идеи почему? При повторном подключении клиента в журналах появляется следующее:

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

Но почему это происходит при подключении, а не отключении?

1 ответ1

1

Когда вы выключаете клиента, у него нет возможности сообщить другой стороне, что он уходит. Единственный способ сказать, что узел ушел, - это попытаться отправить что-то ему и заметить, что он не отвечает.

Если в вашем приложении требуется, чтобы обнаруживался мертвый одноранговый узел, вам необходимо реализовать обнаружение мертвого однорангового узла. Вы можете сделать это, включив опцию keepalive в socat , но это может занять несколько часов, чтобы обнаружить мертвого партнера. Вы также можете сделать это, отправляя что-то периодически - отправка будет иметь тайм-аут, если узел мертв, вызывая обнаружение. Если предполагается, что другая сторона отправляет вам данные, вы можете прервать ее, если вы не получили ожидаемые данные (возможно, с помощью флага socat -T ).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .