Возможно ли, чтобы TCP-соединение оставалось открытым, когда клиент отключился?

12

У нас есть серверное приложение, которое сталкивается с проблемами исчерпания TCP при 4000 соединений. Это будет происходить каждые 3 или 4 недели (приблизительно). Поставщик, который создал это серверное приложение, после проверки вывода команды netstat -b сообщает нам, что некоторые соединения остаются открытыми, даже если клиенты были сброшены.

Мне было поручено выяснить, почему конкретное клиентское приложение не закрывает TCP-соединение должным образом. Я верю, что если клиентский компьютер выключен, он не может ВОЗМОЖНО сообщить с сервера, что с этим клиентом все еще установлено соединение TCP. К сожалению, я не могу найти какую-либо информацию, чтобы подтвердить мою точку зрения. Я не хочу тратить впустую больше времени на исследование потенциальной проблемы, которая, я не думаю, может даже быть проблемой.

tldr;

Может ли сервер сообщить об установленном соединении с выключенным компьютером?

Джош Смитон
источник

Ответы:

13

TCP не предпринимает никаких усилий для обнаружения мертвого соединения, за исключением стороны, которая передает данные. За это отвечает код приложения, вызывающий стек TCP. Какой протокол здесь задействован? (Тот, что поверх TCP.)

Это ужасно уродливое «решение», но вы можете включить поддержку активности TCP . Там больше в этой статье .

Дэвид Шварц
источник
Вы, вероятно, имели в виду слой и его сессионный уровень поверх транспортного уровня, где находится TCP.
Рилиндо
1
@Rilindo: На практике, и в данном конкретном случае, у вас есть приложение, выполняющее вызовы в стек TCP. Протокол поверх TCP (HTTP, POP или любой другой) обычно указывает, как это сделать, потому что разработчики этих протоколов знали, что TCP не может сделать это сам.
Дэвид Шварц
Упс, моя ошибка. Его слой 7, то.
Рилиндо
Я не собираюсь включать keepalive на этом этапе, но удобно знать, что опция существует. Эта статья, кажется, предполагает, что время уже существует 2 часа. AFAIK, соединения остаются открытыми в течение дней / недель.
Джош Смитон
Скорее всего, keepalive не включены. Некоторый кусок кода должен включить их. Похоже, что приложение просто сломано, если оно даже не включает keepalive и не имеет механизма тайм-аута / пожинания. О каком протоколе мы говорим? (HTTP? SMTP? FTP?)
Дэвид Шварц
8

Да, это возможно. Как указали Дэвид и Пол в своих ответах, в TCP нет механизма (кроме опциональных TCP-запросов, которые необязательны) для обнаружения полуоткрытого соединения. Поставщик приложения должен определить состояние соединения и принять соответствующие меры.

Что касается TCP, то здесь нет обнаружения или различия между полуоткрытым соединением и длинным незанятым соединением.

Вам придется начать устранение неполадок с уровня 1 (физический) модели OSI до уровня 7 (приложение), чтобы выяснить, где возникает проблема. Я бы посоветовал установить и запустить программу захвата пакетов на одном из затронутых клиентов, пока проблема не возникнет, а затем проанализировать захват, чтобы попытаться определить причину, по которой клиент не закрывает соединение.

joeqwerty
источник
3
Или заставьте поставщика реализовать разумные тайм-ауты :)
Шейн Мэдден
5

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

Пол Акерман
источник
Мы знаем клиента, это явная проблема. Это настольное приложение, которым ежедневно пользуются сотни наших пользователей. Я предполагаю, что проблема заключается в сбое приложения, полной перезагрузке или завершении задачи. Я думал, что во всех этих ситуациях сервер будет знать об обрыве соединения.
Джош Смитон
4
Что касается сервера, то соединение открыто, если только он не получает FIN или RST от клиента. Без этого сервер предполагает, что соединение все еще установлено, но у клиента нет данных для отправки. В отношении сервера нет разницы между полуоткрытым соединением и незанятым соединением.
Joeqwerty
@joeqwerty: Правда, однако сервер может решить, что он не хочет держать соединение открытым бесконечно, и может реализовать некоторый механизм тайм-аута / закрытия. Это то, что Дэвид Шварц имел в своем ответе «это ответственность кода приложения». Таким образом, сервер может иметь значение между полуоткрытым соединением и свободным соединением, если он этого хочет. Однако для TCP нет разницы между полуоткрытым соединением и свободным соединением.
Слеське
@sleske: Согласился, что код приложения может это сделать, но TCP не может, если не включена поддержка активности.
Joeqwerty