Сервер c ++ не закрывает соединение через сокет TCP после того, как процесс соединения завершен на клиенте

Я столкнулся с проблемой, которая очень странная для меня

У меня есть приложение (сервер) c ++, развернутое на centos и на стороне клиента (также работает на centos), есть программа, которая соединит сервер через таймер, так что, когда количество соединений достигает 1k, таймер останавливается.

Я могу выполнить следующую команду для обнаружения соединений на сервере:

netstat -nat | grep -i «порт» | grep «УСТАНОВЛЕННЫЙ»

Пока работает прилично. Однако после того, как я завершил процесс с клиента, на УСТАНОВЛЕННОМ СОСТОЯНИИ на сервере все еще оставалось значительное количество соединений. И даже когда я выключил клиентский компьютер, я все еще мог видеть множество активных соединений в состоянии ESTABLISHED на сервере после более чем 10 часов утра следующего дня.

Несмотря на то, что при уничтожении процесса возможна потеря пакетов, из-за которой он не смог уведомить сервер о том, что TCP-соединение закрыто, но я полагаю, что в TCP существует механизм тактового импульса (keepalive) по умолчанию, который может проверить, живо ли соединение.

Достоверно ли получить количество соединений с помощью вышеупомянутой команды, в противном случае может возникнуть проблема, что сервер не освобождает закрытые соединения?

2

Решение

Значения по умолчанию для поддержки активности TCP составляют около 2 часов (в реализациях BSD / Linux). Вы уверены, что у вас настроены параметры TCP keeaplives, когда через 10 часов соединение все еще работает? Я думаю, что ваше приложение, возможно, явно не устанавливает опцию keepalive. Один из способов — использовать опцию get socket и передать SO_TCPKEEPALIVE, чтобы проверить, действительно ли установлен keepalive. И если он не установлен, тогда, пожалуйста, продолжайте и установите его.

Вы можете найти это обсуждение полезным: Как правильно использовать опцию SO_KEEPALIVE, чтобы обнаружить, что клиент на другом конце не работает?

0

Другие решения

Keepalive по умолчанию выкл. Вы должны включить его, в вашем случае на стороне сервера, для каждого сокета.

0

По вопросам рекламы [email protected]