0 / 0 / 0
Регистрация: 15.08.2014
Сообщений: 267
1

Как отследить закрытие клиента http (браузера)

18.09.2023, 21:42. Показов 1546. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый вечер!

Моя программа выполняет роль http/https-сервера.
Когда браузер делает к ней запрос GET, сервер возвращает страницу.
На разных этапах работы я контролирую состояние сокета, через который держу установлено соединение с браузером с помощью функции winsock - getpeername().

Удивляет то, что когда я закрываю браузер, то getpeername() завершается для этого сокета с результатом = 0, т.е. без ошибки.

Получается, что сокет остается "актуальным" после закрытия клиента ?

Если да, то как мне тогда отслеживать ситуацию, когда клиент отвалился (браузер закрыт), чтобы закрыть соединение (закрыть - в смысле, освободить внутренние ресурсы своей программы, а не системные) ?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.09.2023, 21:42
Ответы с готовыми решениями:

www-http сниффер. Как отследить HTTP запросы?
Посмотрел я вот эту статью: ...

Отследить закрытие вкладки и/или отследить соединение
Есть ли какие-то инструменты, чтобы отследить соединение или закрытие вкладки, допустим...

Как отследить закрытие программы
Подскажите пожалуйста как можно отследить закрытие программы(или процесса) из своей программы. ...

Как отследить закрытие страницы
Как при следующих событиях вызвать функцию Function1();, если это возможно? Закрытие текущего...

Как отследить закрытие процесса?
Подскажите пожалуйста, как в C# отслеживать процессы.

5
COM‐пропагандист
781 / 734 / 143
Регистрация: 18.12.2014
Сообщений: 2,084
Записей в блоге: 4
19.09.2023, 13:10 2
Функция read(); возвращает, что прочитано 0 байт.
Это значит что достигнут конец потока, другая сторона закрыла соединение.
Ну или возвращает ошибку когда идёт сбой.

Добавлено через 34 секунды
Цитата Сообщение от LUN2 Посмотреть сообщение
Получается, что сокет остается "актуальным" после закрытия клиента ?
Да, сокеты надо закрывать вручную.
0
0 / 0 / 0
Регистрация: 15.08.2014
Сообщений: 267
20.09.2023, 21:17  [ТС] 3
Замабувараев, но программа желает лишь узнать статус соединения - не закрыл ли его клиент, читать - это не совсем то, что надо.
У меня чтение организовано в другой ветке, где ловится событие FD_READ и данные вычитывается в буфер, потом обрабатываются и т.п.
Если только для получения информации о статусе соединения что-то читать из него ... , а если оно не закрыто и что-то прочитается - это компетенция той ветки, которая обрабатывает чтение.

Т.е., что, в результате "просто узнать" статус соединения нельзя ?
0
852 / 440 / 89
Регистрация: 10.06.2014
Сообщений: 2,615
21.09.2023, 10:05 4
Цитата Сообщение от LUN2 Посмотреть сообщение
программа желает лишь узнать статус соединения
При начале соединения, сохраняете сокет и по умолчанию считаете что это соединение не закрыто.

Если ваша библиотека поддерживает какой нибудь FD_CLOSE, то по нему и определите что соединение закрыто. Если не поддерживает, тогда обычно мультиплексоры выдают событие на чтение при закрытии соединения. Вот в этот момент и можно будет сделать read и получить в результате 0.

Другими словами, если не было FD_CLOSE или read не возвращал 0 при возникновении события, то соединение считается активным.
0
0 / 0 / 0
Регистрация: 15.08.2014
Сообщений: 267
21.09.2023, 21:21  [ТС] 5
Undisputed, про FD_CLOSE тоже подумал, начал ловить его, только не уверен, что правильно его понимаю и действую по его получении.
Насколько я понял, FD_CLOSE я получу, когда удаленный комп (клиент) вызовет свой shutdown, чтобы инициировать закрытие TCP-соединение... Верно ?

В таком случае,

1) если я получу FD_CLOSE и не хочу вычитывать остаток данных из буфера TCP в случае их наличия, то нужно ли мне вызывать shutdown(socket, SD_BOTH) на своей стороне ?
Или сразу вызвать closesocket() ?

2) а если я получу FD_CLOSE и хочу вычитать остаток буфера, то я могу делать это по получении FD_CLOSE или дождаться FD_READ и только после него читать ?

3) а если я буду после FD_CLOSE вычитывать остаток буфера, то мне надо 2 раза вызвать recv() - 1-ый для чтения данных, 2-ой для получения кол-ва байт = 0, как признака соединения ?
Или не надо дожидаться, когда recv() вернет количество = 0 байт.
0
852 / 440 / 89
Регистрация: 10.06.2014
Сообщений: 2,615
22.09.2023, 09:11 6
Лучший ответ Сообщение было отмечено LUN2 как решение

Решение

LUN2,
Мне неизвестно, что и как вы используете в коде. Посмотрите документацию к функциям которые используете и проведите эксперементы. По идее FD_CLOSE должно означать что соединение закрыто тем или иным способом.

Если так, то при получении FD_CLOSE тогда сокет закрыт. Если этого механизма нет, тогда нужно читать из сокета до тех пор, пока не получите 0. Если 0 не получали, считаем что соединение активно
Цитата Сообщение от Undisputed Посмотреть сообщение
обычно мультиплексоры выдают событие на чтение при закрытии соединения

Цитата Сообщение от LUN2 Посмотреть сообщение
1) если я получу FD_CLOSE и не хочу вычитывать остаток данных из буфера TCP в случае их наличия, то нужно ли мне вызывать shutdown(socket, SD_BOTH) на своей стороне ?
Или сразу вызвать closesocket()
Скорее всего вы не получите FD_CLOSE, если в буфере есть данные для чтения

2) аналоично, скорее всего вы не получите FD_CLOSE если в буфере что-то есть

Цитата Сообщение от LUN2 Посмотреть сообщение
а если я буду после FD_CLOSE вычитывать остаток буфера, то мне надо 2 раза вызвать recv() - 1-ый для чтения данных, 2-ой для получения кол-ва байт = 0, как признака соединения ?
После FD_CLOSE вы врядли сможете что-то прочитать из сокета

За деталями обращайтесь к докам функций/библиотек которые используете
1
22.09.2023, 09:11
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.09.2023, 09:11
Помогаю со студенческими работами здесь

Как отследить закрытие папки в проводнике?
Доброго времени суток. У меня задача: при закрытии папки в проводнике нужно зашифровать все файлы,...

Как отследить закрытие дочернего окна?
Есть 2 окна: родительское - MainWindow, дочернее - Dialog. По нажатию кнопки в окне "MainWindow"...

как отследить закрытие основного окна?
body onunload это понятно что не то, это просто уход со страницы, а вот если юзер нажал "крестик...

Как отследить кастомное закрытие приложения?
есть дефолтное MainWindow w; CloseEvent в MainWindow: protected: void closeEvent(QCloseEvent...

Как отследить закрытие самой программы а не формы
Нужно отследить закрытие программы. (не formclosing и не formclosed) И когда программа закрывалась...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru