#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 минут раньше были отключены у пары американских операторов (у других это дольше). Однако вы должны знать, что они могут изменить это значение в любой момент, поэтому, если ваше приложение рассчитывает на это как на часть своей функциональности, вам может стать интересно, если вы решите это сделать.
К вашему сведению…