Keep-Alive
От: Tessi  
Дата: 28.08.23 17:15
Оценка:
Я хочу сделать в своем клиенском приложении поддержку keep-alive (знаю, что сервер опцию поддерживает).
Я выставляю сокету опцию SO_KEEPALIVE. При этом сервер видит это и не закрывает соединение.

Вопрос — кроме выставление флага SO_KEEPALIVE, нужно ли держать сокет открытым (не делать closesocket)?
Но в этом случае непонятно, зачем нужен SO_KEEPALIVE, ведь сервер и так видит, что клиент не отсоединился и может ждать новых запросов.

Или же можно закрыть сокет и в следующий раз новый сокет будет использовать существующее соединение автоматически и это реализовано внутри ТСР?

B целом главный вопрос — как переиспользовать существующее соединение с сервером?


Я набросал маленький клиент на коленке, который сокет открывает->флаг->подключается->закрывает, я вижу (через Windows Resource Monitor), что соединение не закрывается в течение ~30 секунд, но второй созданный плле этого сокет создает уже новое соединение. Хотя я думал, что новый сокет будет использовать первое соединение, которое висит открытым, но чей сокет я закрыл.

Или со стороны клиента сокет=соединение?

Подскажите, как именно реализовано keep-alive соединение и как переиспользовать созданное keep-alive соединение.
Re: Keep-Alive
От: Pzz Россия https://github.com/alexpevzner
Дата: 28.08.23 18:22
Оценка:
Здравствуйте, Tessi, Вы писали:


T>Я хочу сделать в своем клиенском приложении поддержку keep-alive (знаю, что сервер опцию поддерживает).

T>Я выставляю сокету опцию SO_KEEPALIVE. При этом сервер видит это и не закрывает соединение.

У тебя протокол какой. Я понимаю, что TCP, а выше TCP — что?

T>Вопрос — кроме выставление флага SO_KEEPALIVE, нужно ли держать сокет открытым (не делать closesocket)?

T>Но в этом случае непонятно, зачем нужен SO_KEEPALIVE, ведь сервер и так видит, что клиент не отсоединился и может ждать новых запросов.

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

Только вот TCP keep-alive плохо справляется с этой задачей. И толку от него не очень-то много.

Лучше сделать аналог прикладного уровня, если протокол позволяет.
Re: Keep-Alive
От: Anton Batenev Россия https://github.com/abbat
Дата: 28.08.23 18:31
Оценка: 9 (1)
Здравствуйте, Tessi, Вы писали:

T> Я хочу сделать в своем клиенском приложении поддержку keep-alive (знаю, что сервер опцию поддерживает).


Судя по описанию, ты хочешь http keep-alive, а не tcp keep-alive (который ты пытаешься включить через SO_KEEPALIVE).
Re: Keep-Alive
От: vsb Казахстан  
Дата: 28.08.23 18:40
Оценка:
Рекомендую для начала прочитать, что такое TCP keepalive. Судя по вопросу понимания этого нет, поэтому тут обсуждать что-либо смысла нет.

https://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html можно тут почитать. Или тут: https://en.wikipedia.org/wiki/Keepalive
Отредактировано 28.08.2023 18:43 vsb . Предыдущая версия . Еще …
Отредактировано 28.08.2023 18:42 vsb . Предыдущая версия .
Re[2]: Keep-Alive
От: Tessi  
Дата: 28.08.23 22:12
Оценка:
Здравствуйте, Anton Batenev, Вы писали:

AB>Здравствуйте, Tessi, Вы писали:


T>> Я хочу сделать в своем клиенском приложении поддержку keep-alive (знаю, что сервер опцию поддерживает).


AB>Судя по описанию, ты хочешь http keep-alive, а не tcp keep-alive (который ты пытаешься включить через SO_KEEPALIVE).


Да, сервер требует http Keep-Alive.
Мы посылаем в хедере Connection: Keep-Alive и сервер успокоился. Но настоящей поддержки Keep-Alive нет, т.к. если нужно всегда использовать создаенное соединение, отслеживать, живо ли оно и прочее — это потребует переписывать код

Ну и внутри же все равно сокеты.

Из описания: The Hypertext Transfer Protocol uses the keyword "Keep-Alive" in the "Connection" header to signal that the connection should be kept open for further messages.

Это для сервера означает, чио нужно держать соединение.

И остается тот же вопрос — для обеспечения Keep-Alive коннекшена со стороны клиента требуется всегда использовать тот же сокет или его можно закрывать и потом открывать новый — и автоматически заюзается тот же коннекшн?
Как понимать термин "переиспользовать коннекшн" с точки зрения клиента?

Да, я, если честно, запутался. Я сети вплотную изучал много лет назад и сейчас таких нюансов не помню уже, потому что ни разу до этого не сталкивался.
С точки зрения логики TCP keep-alive требует использовать один и тот же открытый однажды сокет, пока соединение живо.
А с точки зрения http keep-alive что от клиента требуется?
Re[3]: Keep-Alive
От: Pzz Россия https://github.com/alexpevzner
Дата: 28.08.23 22:43
Оценка:
Здравствуйте, Tessi, Вы писали:

T>А с точки зрения http keep-alive что от клиента требуется?


С точки зрения http keep-alive лучшее, что может сделать клиент (при таком уровне знаний его автора, не сочти за грубость) — это не пытаться реализовать HTTP на сокетах, а использовать готовую библиотеку (выбор которой зависит от языка) — а она уж позаботится о сокетах и прочих низкоуровневых деталях.

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

Модель HTTP заключается в том, что послали запрос/получили ответ. Как оно там внутри на сокеты ложится, дело десятое.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.