время ожидания TCP для операторов США (или любого другого оператора, если на то пошло)

#android #tcp #timeout

#Android #tcp #время ожидания

Вопрос:

Насколько я понимаю, операторы удаляют все tcp-соединения, которые простаивают в течение некоторого количества минут. Вот почему, если вы хотите поддерживать постоянное tcp-соединение от ваших клиентов к вашему бэкэнду, вы должны отправлять keep-alive в оба способа.

Мой вопрос: каким должен быть этот интервал ожидания?

Ответ №1:

Чтобы было ясно, никто не может удалить TCP-соединение, кроме конечных точек. Это потому, что сетевой протокол IP — это все, что видит сеть, и он не имеет состояния по своей конструкции.

Однако «конечная точка» может быть не такой, как вы ожидаете. Оператор может поместить прозрачный прокси-сервер или маршрутизатор с NAT между ними, и в этот момент им необходимо сохранять состояние, чтобы правильно пересылать данные.

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

Включение SO_KEEPALIVE имеет значение по умолчанию 2 часа. Таким образом, хорошо работающий маршрутизатор должен сохранять состояние по крайней мере так долго, но не ставьте на это ферму.

Чтобы ответить на ваш конкретный вопрос… На моем месте я бы потратил 15 минут или меньше.

Обратите внимание, что только одна сторона должна отправлять keep-alive во время работы, повторно отправляя последний 1 байт потока данных, как если бы он был потерян в сети. Получатель отбрасывает его, потому что он уже видел его, но отправляет новое подтверждение в ответ, что приводит к тому, что трафик направляется в обоих направлениях.

Комментарии:

1. но afaik SO_KEEPALIVE нелегко настроить

2. int delay = X; setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE,amp;delay,sizeof(задержка)); int count = X; setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT,amp;count, sizeof(количество)); int interval = X; setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL,amp;interval, sizeof(интервал)); int enable = 1; setsockopt(sockfd, SOL_SOCKET,SO_KEEPALIVE,amp;включить,sizeof(включить));

Ответ №2:

Это нужно будет делать только сломанным NAT. AIUI, разумный NAT может просто отправить TCP keepalives на оба конца соединения, когда ему нужно проверить работоспособность, и разорвать соединение, если достаточное их количество не вызовет ответа.

Увы, многие / большинство NATS сломаны.

Кстати, в «многозадачности» iOS есть функция «voip», которая отменит приостановку работы вашего приложения, если ваш сокет получит данные, или, необязательно, через приблизительные промежутки времени (например, для keepalives); минимальный интервал составляет что-то вроде 300 секунд, так что, вероятно, сработает что-то между 300-1200.

Ответ №3:

Поскольку я не знаю ваших конкретных причин, по которым вы поддерживаете соединение, даже несмотря на то, что, по-видимому, нет никакого трафика связи, 5 минут раньше были отключены у пары американских операторов (у других это дольше). Однако вы должны знать, что они могут изменить это значение в любой момент, поэтому, если ваше приложение рассчитывает на это как на часть своей функциональности, вам может стать интересно, если вы решите это сделать.

К вашему сведению…