Как обрабатывать TCP keepalive в приложении

У меня есть приложение TCP, работающее на VxWorks. У меня установлена ​​опция SO_KEEPALIVE для TCP-соединений. Мое приложение отслеживает все TCP-соединения и помещает их в список ссылок.

Если клиент долго бездействует, мы видим, что соединение закрывается. Соединение не указано в выводе netstat.

Поскольку соединение закрывается стеком TCP, ресурсы, выделенные для этого соединения, не очищаются. Не могли бы вы помочь мне понять, как приложение получает уведомление, если соединение закрыто из-за сбоев поддержки активности.


person Vikash Jain    schedule 21.05.2015    source источник


Ответы (3)


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

В большинстве реализаций TCP/IP вы можете определить, закрыто ли соединение, попытавшись прочитать его.

person Warren Dew    schedule 21.05.2015
comment
Спасибо, да, чтение/запись с близкого соединения может помочь. Я хочу понять, лучший ли это способ сделать это или есть и другие подходы. - person Vikash Jain; 21.05.2015
comment
Это может зависеть от того, какую именно реализацию TCP/IP вы используете, но в большинстве реализаций, которые я видел, чтение (а не запись) — лучший способ сделать это. - person Warren Dew; 21.05.2015
comment
Как маршрутизатор может разорвать соединение между двумя одноранговыми узлами? - person Philip Stuyck; 22.05.2015
comment
@PhilipStuyck Отправляя FIN или RST. - person user207421; 22.05.2015

Из этой ссылки: http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html

Я цитирую :

Эта процедура полезна, потому что, если другие одноранговые узлы потеряют соединение (например, при перезагрузке), вы заметите, что соединение разорвано, даже если на нем нет трафика. Если ваш узел не отвечает на проверки активности, вы можете утверждать, что соединение нельзя считать действительным, а затем предпринять правильные действия.

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

Для таких случаев существует Keepalive.

С точки зрения TCP в Keep Alive нет ничего особенного. И, следовательно, если одноранговый узел не сможет подтвердить поддержку активности, вы получите 0 байтов в своем сокете, и вам придется закрыть свой конец сокета. Это единственное корректирующее действие, которое вы можете предпринять в данный момент.

person Philip Stuyck    schedule 22.05.2015

Поскольку соединение закрывается стеком TCP, ресурсы, выделенные для этого соединения, не очищаются.

Только если вы больше никогда не воспользуетесь соединением.

Если клиент долго бездействует, мы видим, что соединение закрывается. Соединение не указано в выводе netstat.

Прими решение. Либо ты это видишь, либо нет. То, что вы увидите, это порт CLOSE_WAIT в netstat.

Не могли бы вы помочь мне понять, как приложение получает уведомление, если соединение закрыто из-за сбоев поддержки активности.

В следующий раз, когда вы будете использовать соединение для чтения или записи, вы получите ECONNRESET.

person user207421    schedule 22.05.2015