Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.137.185.180] |
|
Сообщ.
#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 соединениях управляемые идентификаторами сессии |
Сообщ.
#16
,
|
|
|
Цитата BlackEmperor @ Вспомнилось... Есть такая идея, реализованная уже в какой-то системе одного моего коллеги дааавно, ты не держишь коннект клиента, а при при первом подключении клиенту даешь некий идентификатор сессии, и закрываешь соединение, отдав этот ид клиенту (своего рода вирт хэндл). Клиент при каждом обращении к серверу передает этот идентификатор сессии на сервер и по нему выполняет операцию. Итог: один запрос один коннект и закрытие коннекта, а каждый запрос, начиная со второго, идет с полученным ид сессии. На сервере периодически чистишь идешники сессий, скажем по принципу не было ни одного запроса с неким ид за некий таймаут. И получаешь некие своего рода датаграммы на TCP соединениях управляемые идентификаторами сессии ну тут конечно можно не изобретать велосипед. Ли использовать модель сетевых событий, ли на каждый коннект свой поток. Но придется все-равно хранить идентификаторы для корректного завершения соединений. |
Сообщ.
#17
,
|
|
|
В общем, вариантов в теме предложили несколько - выбирай
|
Сообщ.
#18
,
|
|
|
Цитата zss @ ли на каждый коннект свой поток. У меня большое сомнения что при реализации сервера как то иначе будет правильно. |