Задать вопрос

Правильно ли завершается TCP соединение с браузером?

Я пишу веб-сервер и похоже при взаимодействии с браузером происходит недопонимание.
В браузере открываю веб-страницу, браузер успешно посылает HTTP запрос и успешно принимает HTTP ответ, сразу же после отправки ответа, мой веб-сервер закрывает подключение, но браузер тут-же создаёт новое подключение, однако он не присылает никаких запросов в этом подключении, после 5 секунд соединение разрывается сервером, поскольку на нём стоит тайм-аут для чтения.
Браузер присылает заголовок Connection: keep-alive
Сервер отправляет заголовок "Connection: close", поскольку я хочу просто отправить ответ и закрыть соединение.

Вот как это выглядит в Wireshark:
У сервера порт 7878, остальные браузеру.
6664906d282ae218104852.png

Вплоть до 29 пакета всё кажется идёт хорошо, но в 29 пакете браузер пытается отправить ACK, как я понял в ответ на FIN ACK, но похоже тут что-то не так.
У меня подозрение, что в после того как сервер в 28 пакете отправил FIN ACK он не дожидается ACK от клиента, верно ли это?

Я поставил цикл из 10000 вызовов sleep(1 мс) перед завершением соединения сервером(что-бы возможно где-то между ними соединение успело завершиться), в этом варианте клиенту с сервером чуть-чуть не хватило что-бы полностью обработать последовательность:
FIN ACK ->
<- ACK
<- FIN ACK
-> ACK
Тут инициатором завершения был клиент
6664984bd6a56728955211.png

Правильно ли я понимаю, что сервер посылая FIN ACK не дожидается ACK и в целом неверно производит завершение TCP подключения, завершая соединение раньше времени? Именно поэтому браузер инициирует повторное подключение, но не присылает никаких данных.

Я попробовал отправлять запрос с помощью сторонней утилиты, в этом случае соединение завершается корректно
6664a7fc76527001852959.png

Похоже, что эта проблема связана только с браузером(я пробовал разные браузеры).
  • Вопрос задан
  • 416 просмотров
Подписаться 4 Средний 5 комментариев
Решения вопроса 1
15432
@15432
Системный программист ^_^
Вплоть до 29 пакета всё кажется идёт хорошо, но в 29 пакете браузер пытается отправить ACK, как я понял в ответ на FIN ACK, но похоже тут что-то не так.

всё ок, браузер почему-то отправил сразу два ACK, без учета FIN (29) и с учетом FIN (30). Ну лишний пакет получился, и ладно. Последовательность FIN/ACK завершена корректно.

У меня подозрение, что в после того как сервер в 28 пакете отправил FIN ACK он не дожидается ACK от клиента, верно ли это?

не, там всё нормально

но браузер тут-же создаёт новое подключение

не, там браузер сразу два соединения создал. так делается для оптимизации - чтобы быстрее загрузить что-нибудь ещё. обычно на странице много контента и помимо первого GET образуются много других GET. Но в вашем случае этого не происходит и соединение не пригождается.

не присылает никаких запросов в этом подключении

видимо в index.html не было больше ничего, что можно запросить

поскольку я хочу просто отправить ответ и закрыть соединение

так и вышло, но в первом соединении. второе так и висело на всякий случай.

в этом варианте клиенту с сервером чуть-чуть не хватило что-бы полностью обработать последовательность:

да не чуть-чуть, здесь вместо закрытия по таймауту (FIN), на стороне сервера соединение закрылось по RST (видимо по закрытию приложения сервера или по системному таймауту), клиент и не думал начинать закрывать сокет. логично - браузер всё ещё надеется, что вы откроете другую страничку

Правильно ли я понимаю, что сервер посылая FIN ACK не дожидается ACK и в целом неверно производит завершение TCP подключения, завершая соединение раньше времени?

всё корректно дожидается, тут проблем нет

Именно поэтому браузер инициирует повторное подключение, но не присылает никаких данных.

нет, браузер именно сразу при подключении открывает два соединения (обратите внимание на два SYN в самом начале), для более быстрой обработки ваших запросов. разработчики браузера стараются как можно сильнее ускорить работу, вот и идут на такие ухищрения.

Я попробовал отправлять запрос с помощью сторонней утилиты, в этом случае соединение завершается корректно

а тут всего одно соединение, без второго висящего в ожидании. утилита проста как тапок, сказали подключиться, подключается, без дополнительных оптимизаций и соединений "на будущее"

(я пробовал разные браузеры)

видимо все браузеры конкурируют по скорости работы с Web и делают такую оптимизацию
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы