Я хочу сделать в своем клиенском приложении поддержку keep-alive (знаю, что сервер опцию поддерживает).
Я выставляю сокету опцию SO_KEEPALIVE. При этом сервер видит это и не закрывает соединение.
Вопрос — кроме выставление флага SO_KEEPALIVE, нужно ли держать сокет открытым (не делать closesocket)?
Но в этом случае непонятно, зачем нужен SO_KEEPALIVE, ведь сервер и так видит, что клиент не отсоединился и может ждать новых запросов.
Или же можно закрыть сокет и в следующий раз новый сокет будет использовать существующее соединение автоматически и это реализовано внутри ТСР?
B целом главный вопрос — как переиспользовать существующее соединение с сервером?
Я набросал маленький клиент на коленке, который сокет открывает->флаг->подключается->закрывает, я вижу (через Windows Resource Monitor), что соединение не закрывается в течение ~30 секунд, но второй созданный плле этого сокет создает уже новое соединение. Хотя я думал, что новый сокет будет использовать первое соединение, которое висит открытым, но чей сокет я закрыл.
Или со стороны клиента сокет=соединение?
Подскажите, как именно реализовано keep-alive соединение и как переиспользовать созданное keep-alive соединение.
T>Я хочу сделать в своем клиенском приложении поддержку keep-alive (знаю, что сервер опцию поддерживает). T>Я выставляю сокету опцию SO_KEEPALIVE. При этом сервер видит это и не закрывает соединение.
У тебя протокол какой. Я понимаю, что TCP, а выше TCP — что?
T>Вопрос — кроме выставление флага SO_KEEPALIVE, нужно ли держать сокет открытым (не делать closesocket)? T>Но в этом случае непонятно, зачем нужен SO_KEEPALIVE, ведь сервер и так видит, что клиент не отсоединился и может ждать новых запросов.
SO_KEEPALIVE нужен, чтобы если соединение формально открыто, но фактически никакие данные по нему долгое время не ходят, и если вдруг соединение по каким-то причинам сломается (ну, например, пришла мышка, перегрызла кабель), то обе стороны в конечном итоге заметили потерю соединения и закрыли его. Ну там, для порядку и экономии ресурсов.
Только вот TCP keep-alive плохо справляется с этой задачей. И толку от него не очень-то много.
Лучше сделать аналог прикладного уровня, если протокол позволяет.
Здравствуйте, 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 что от клиента требуется?
Здравствуйте, Tessi, Вы писали:
T>А с точки зрения http keep-alive что от клиента требуется?
С точки зрения http keep-alive лучшее, что может сделать клиент (при таком уровне знаний его автора, не сочти за грубость) — это не пытаться реализовать HTTP на сокетах, а использовать готовую библиотеку (выбор которой зависит от языка) — а она уж позаботится о сокетах и прочих низкоуровневых деталях.
Кроме того, и это важно, надо понимать, что в высокоуровневом интерфейсе протокола HTTP нет такого понятия, как HTTP соединение. Клиент волен использовать одно и то же соединение, или открывать новое на каждый запрос, или открыть несколько и использовать их для каждого следующего запроса по кругу — это все детали реализации, высокоуровневый код не должен от них зависеть.
Модель HTTP заключается в том, что послали запрос/получили ответ. Как оно там внутри на сокеты ложится, дело десятое.