
Принимая во вниманиеописание TCP_USER_TIMEOUT:
Если значение больше 0, оно указывает максимальный период времени в миллисекундах, в течение которого переданные данные могут оставаться неподтвержденными, прежде чем TCP принудительно закроет соответствующее соединение и вернет ETIMEDOUT приложению.
Очень короткие значения USER TIMEOUT могут повлиять на TCP-передачи по путям с высокой задержкой. Если пользовательский тайм-аут происходит до того, как приходит подтверждение для невыполненного сегмента, возможно, из-за потери пакета, соединение закрывается. Многие реализации TCP по умолчанию используют значения USER TIMEOUT в несколько минут. Хотя опция UTO позволяет предлагать короткие тайм-ауты, приложения, объявляющие их, должны учитывать эти эффекты.
Я ожидал, что TCP_USER_TIMEOUT в 2 мс будет иметь катастрофические последствия: в сети, где RTT меньше 2 мс, каждый отправленный пакет TCP будет ожидать ACK, и соединение будет закрыто. Однако в моей среде я этого не наблюдаю. Подключения могут быть установлены, и данные отправляются и принимаются нормально. Однако я замечаю, что если я дергаю шнур или выключаю принимающий интерфейс, TCP_USER_TIMEOUT эффективно обнаруживает потерю соединения, и соединение закрывается своевременно. Итак, TCP_USER_TIMEOUT работает, просто не так, как я ожидал.
Что я не понимаю в TCP_USER_TIMEOUT? Почему значения ниже RTT не приводят к разрыву соединения?
Если это будет полезно, мой клиент — это компьютер Scientific Linux 6.1 с ядром 2.6.32.
решение1
Реализация UTO в Linux была неточной и была недавно исправлена этим набором исправлений: (на всякий случай, если вы не являетесь автором этого набора исправлений): https://lkml.org/lkml/2018/7/18/1090
Однако даже после срабатывания UTO хост прекращает повторную передачу и переходит в состояние TCP_CLOSE, но не сбрасывает соединение. Это ответственность приложения, отправляющего RST.