Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.217.109.151] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
на сервере на accept создаются соединения.
при завершении работы серверного приложения хотелось бы закрыть соединения ассоциированные с серверным сокетом. Т.к. сами соединения (сокеты) не хранятся на сервере, то сделать им closesocket нет возможности. Можно ли как закрыть все соединения ассоциированные с серверным сокетом ? |
Сообщ.
#2
,
|
|
|
zss
Какой то абстрактный вопрос. Это логическая задача? |
Сообщ.
#3
,
|
|
|
Цитата Urich @ акой то абстрактный вопрос. Это логическая задача? практическая |
Сообщ.
#4
,
|
|
|
zss
Выставлять keepalive в пару минут. |
Сообщ.
#5
,
|
|
|
Цитата Urich @ Выставлять keepalive в пару минут не поможет. Смысл в следующем. Сервер запускает поток в котором слушает сокет. Если состоялось соединение то от вызывает синхронный метод обработки соединения. Если происходит остановка сервера, то перед завершением потока происходит закрытие серверного сокета и ожидание завершения потока. Но если в данный момент есть клиентское соединение, то завершение потока приходится ждать пока клиент не отключится. Поэтому хотелось бы закрывать не только серверный сокет, но и все ассоциированный с ним соединения. |
Сообщ.
#6
,
|
|
|
При приходе команды о закрытии сервера, закрываешь серверный слушающий сокет и в цикле пробегаешь по всем сокетам и закрываешь их, а каждая процедура обработки клиентского запроса должна быть прерываема (проверять некий флаг и завершать если надо) и ессно в цикле проставляешь флаг на закрытие
|
Сообщ.
#7
,
|
|
|
Цитата BlackEmperor @ При приходе команды о закрытии сервера, закрываешь серверный слушающий сокет и в цикле пробегаешь по всем сокетам и закрываешь их, а каждая процедура обработки клиентского запроса должна быть прерываема для этого их нужно хранить. а я их не храню. Зачем ? пришел клиент - отдал его обрабатывающему потоку и пусть себе там варится. Как только отвалится - поток сам умрет. |
Сообщ.
#8
,
|
|
|
Ну и храни в потоке, а еще храни флаг доступный из вне потока, как он скажем false прерывай поток и закрывай сокет, т.е. не прерывай, а выходи из поточной проц, а поток ессно помрет. А храни глоб тбл флагов для потоков, парами флаг + ид потока, ид понадобиться чтоб периодически чистить тбл от записей потоки которые уже не существуют, это чтоб с каждого потока не лазить в тбл для удалении своей записи при завершении, а с неким таймаутом запускай ф-юю чистки тбл
|
Сообщ.
#9
,
|
|
|
BlackEmperor прав. ну нельзя закрывать соединения простой ошибкой сокета. А вот понадобится вам передавать клиентам перед завершением какой-то код окончания работы? Опять мучиться будете. Просто действительно сделайте некий флаг завершения работы и в потоках его смотрите.
|
Сообщ.
#10
,
|
|
|
Цитата HOMO_PROGRAMMATIS @ BlackEmperor прав. ну нельзя закрывать соединения простой ошибкой сокета. А вот понадобится вам передавать клиентам перед завершением какой-то код окончания работы? Опять мучиться будете. Просто действительно сделайте некий флаг завершения работы и в потоках его смотрите. ну у меня так было сделано 100 лет назад. Базовый класс-поток, который ждет соединение в потоке. Пришло соединение - дергает чисто виртуальный метод. То есть наследник будет сам решать что делать. Он как раз крутит бесконечный цикл и выходит с него только при закрытии сокета. Добавлено тут еще один прикол есть. Если соединение не стабильное (например GPRS) и пытаться корректно завершить поток, то можно очень долго ждать его завершения т.к. передача нескольких Кбайт может идти несколько минут (проверено ) |
Сообщ.
#11
,
|
|
|
Даешь некоторое время на закрытие потоку, не закрылся,килишь его. Некрасиво, но четко. Да и все равно сервер на остановку идет
|
Сообщ.
#12
,
|
|
|
Цитата BlackEmperor @ Даешь некоторое время на закрытие потоку, не закрылся,килишь его. Некрасиво, но четко. Да и все равно сервер на остановку идет а если критический код выполняется ? не хотелось бы так. Хочется корректно завершить. Можно конечно не держать соединение, при каждом запросе устанавливать новое. Тогда не нужно крутить бесконечный цикл. Но правильно ли это ? То есть тут встает вопрос правильной реализации серверной обработки т.к. я наверное не правильно сделал. |
Сообщ.
#13
,
|
|
|
Если такая проблема с тем что малые операции могут долго работатать - то держи все же хендлы сокетов и делай им Abort из главного потока если совсем все затянулось, а дальше по тексту. У нас так и делается примерно.
|
Сообщ.
#14
,
|
|
|
Цитата HOMO_PROGRAMMATIS @ Если такая проблема с тем что малые операции могут долго работатать так я и спрашиваю, что лучше - держать описатели или постоянно при каждом запросе создавать новое соединение ? Тут правда встает вопрос в установке соединения на плохом канале... |
Сообщ.
#15
,
|
|
|
Вспомнилось...
Есть такая идея, реализованная уже в какой-то системе одного моего коллеги дааавно, ты не держишь коннект клиента, а при при первом подключении клиенту даешь некий идентификатор сессии, и закрываешь соединение, отдав этот ид клиенту (своего рода вирт хэндл). Клиент при каждом обращении к серверу передает этот идентификатор сессии на сервер и по нему выполняет операцию. Итог: один запрос один коннект и закрытие коннекта, а каждый запрос, начиная со второго, идет с полученным ид сессии. На сервере периодически чистишь идешники сессий, скажем по принципу не было ни одного запроса с неким ид за некий таймаут. И получаешь некие своего рода датаграммы на TCP соединениях управляемые идентификаторами сессии |