Что происходит с TCP-соединением во время тайм-аута сокета

#java #c #linux #tcp #operating-system

Вопрос:

Допустим, у нас есть веб-клиент Java, такой как spring RestTemplate . Он может быть настроен с таймаутом чтения:

 RestTemplateBuilder()  .setReadTimeout(Duration.ofMillis(1000))  .build()  

Если выполняется вызов http и сервер медленно отвечает, будет выдано исключение: java.net.SocketTimeoutException

Вопрос в следующем: что происходит с базовым TCP-соединением, когда наступает тайм-аут?

Из того, что я могу сказать RestTemplate , использует SocketInputStream ниже, который, в свою очередь, использует родной poll язык в Linux. poll принимает параметр тайм-аута, но закрывает ли он соединение при наступлении тайм-аута? Если нет, то что произойдет с ответом, когда он будет получен?

Как поведение тайм-аутов отличается между Http1 и Http2 (которые поддерживают мультиплексирование по одному TCP-соединению)?

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

1. На уровне сокета во время ожидания ничего не происходит, кроме возврата вызова. Вы можете представить себе цикл опроса, в котором вы время от времени проверяете поступление данных, используя тайм-аут, чтобы убедиться, что вы не блокируетесь на «слишком долгое» ожидание. Это поддается проверке простым экспериментом.

2. @user16632363 значит, соединение осталось висеть? Когда он закрывается, если нет ответа? после истечения срока действия «сохранить жизнь»? И что, если есть ответ после тайм-аута, он отбрасывается?

3. Я далек от эксперта, но я думаю, что в программном обеспечении потребительского класса вызов сокета либо не блокируется, либо, если он блокируется, запускается другой поток для проверки времени ожидания. Когда наступает тайм-аут, сокет просто отбрасывается (с закрытием), и, если сервер ответит позже, он просто отправляется на сетевую карту клиента и отбрасывается. ОС не проверяет поступление пакетов, так как соединение закрыто, поэтому она просто ничего не делает. Возможно, ОС все еще получает пакеты, хотя. Я не так уверен, так как я никогда не писал драйвер Ethernet/WIFI.

4. Это не «оставлено в подвешенном состоянии». Опрос с истекшим временем ожидания оставляет сокет и базовое TCP-соединение в том же состоянии, в котором вы вообще не вызывали опрос. Полученные данные остаются в сокете до тех пор, пока не будут получены. Сокет закрывается, когда вы вызываете close.