На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
    > закрыть соединения
      на сервере на accept создаются соединения.
      при завершении работы серверного приложения хотелось бы закрыть соединения ассоциированные с серверным сокетом.
      Т.к. сами соединения (сокеты) не хранятся на сервере, то сделать им closesocket нет возможности.

      Можно ли как закрыть все соединения ассоциированные с серверным сокетом ?
        zss
        Какой то абстрактный вопрос. Это логическая задача?
          Цитата Urich @
          акой то абстрактный вопрос. Это логическая задача?

          практическая
            zss
            Выставлять keepalive в пару минут.
              Цитата Urich @
              Выставлять keepalive в пару минут

              не поможет.

              Смысл в следующем. Сервер запускает поток в котором слушает сокет. Если состоялось соединение то от вызывает синхронный метод обработки соединения.

              Если происходит остановка сервера, то перед завершением потока происходит закрытие серверного сокета и ожидание завершения потока.
              Но если в данный момент есть клиентское соединение, то завершение потока приходится ждать пока клиент не отключится.
              Поэтому хотелось бы закрывать не только серверный сокет, но и все ассоциированный с ним соединения.
                При приходе команды о закрытии сервера, закрываешь серверный слушающий сокет и в цикле пробегаешь по всем сокетам и закрываешь их, а каждая процедура обработки клиентского запроса должна быть прерываема (проверять некий флаг и завершать если надо) и ессно в цикле проставляешь флаг на закрытие
                  Цитата BlackEmperor @
                  При приходе команды о закрытии сервера, закрываешь серверный слушающий сокет и в цикле пробегаешь по всем сокетам и закрываешь их, а каждая процедура обработки клиентского запроса должна быть прерываема

                  для этого их нужно хранить. а я их не храню. Зачем ? пришел клиент - отдал его обрабатывающему потоку и пусть себе там варится.
                  Как только отвалится - поток сам умрет.
                    Ну и храни в потоке, а еще храни флаг доступный из вне потока, как он скажем false прерывай поток и закрывай сокет, т.е. не прерывай, а выходи из поточной проц, а поток ессно помрет. А храни глоб тбл флагов для потоков, парами флаг + ид потока, ид понадобиться чтоб периодически чистить тбл от записей потоки которые уже не существуют, это чтоб с каждого потока не лазить в тбл для удалении своей записи при завершении, а с неким таймаутом запускай ф-юю чистки тбл
                      BlackEmperor прав. ну нельзя закрывать соединения простой ошибкой сокета. А вот понадобится вам передавать клиентам перед завершением какой-то код окончания работы? Опять мучиться будете. Просто действительно сделайте некий флаг завершения работы и в потоках его смотрите.
                        Цитата HOMO_PROGRAMMATIS @
                        BlackEmperor прав. ну нельзя закрывать соединения простой ошибкой сокета. А вот понадобится вам передавать клиентам перед завершением какой-то код окончания работы? Опять мучиться будете. Просто действительно сделайте некий флаг завершения работы и в потоках его смотрите.

                        ну у меня так было сделано 100 лет назад. Базовый класс-поток, который ждет соединение в потоке.
                        Пришло соединение - дергает чисто виртуальный метод. То есть наследник будет сам решать что делать.

                        Он как раз крутит бесконечный цикл и выходит с него только при закрытии сокета.

                        Добавлено
                        тут еще один прикол есть. Если соединение не стабильное (например GPRS) и пытаться корректно завершить поток, то можно очень долго ждать его завершения т.к. передача нескольких Кбайт может идти несколько минут (проверено :))
                          Даешь некоторое время на закрытие потоку, не закрылся,килишь его. Некрасиво, но четко. Да и все равно сервер на остановку идет
                            Цитата BlackEmperor @
                            Даешь некоторое время на закрытие потоку, не закрылся,килишь его. Некрасиво, но четко. Да и все равно сервер на остановку идет

                            а если критический код выполняется ? не хотелось бы так. Хочется корректно завершить.

                            Можно конечно не держать соединение, при каждом запросе устанавливать новое. Тогда не нужно крутить бесконечный цикл.
                            Но правильно ли это ?

                            То есть тут встает вопрос правильной реализации серверной обработки т.к. я наверное не правильно сделал.
                              Если такая проблема с тем что малые операции могут долго работатать - то держи все же хендлы сокетов и делай им Abort из главного потока если совсем все затянулось, а дальше по тексту. У нас так и делается примерно.
                                Цитата HOMO_PROGRAMMATIS @
                                Если такая проблема с тем что малые операции могут долго работатать

                                так я и спрашиваю, что лучше - держать описатели или постоянно при каждом запросе создавать новое соединение ?
                                Тут правда встает вопрос в установке соединения на плохом канале...
                                  Вспомнилось...
                                  Есть такая идея, реализованная уже в какой-то системе одного моего коллеги дааавно, ты не держишь коннект клиента, а при при первом подключении клиенту даешь некий идентификатор сессии, и закрываешь соединение, отдав этот ид клиенту (своего рода вирт хэндл). Клиент при каждом обращении к серверу передает этот идентификатор сессии на сервер и по нему выполняет операцию. Итог: один запрос один коннект и закрытие коннекта, а каждый запрос, начиная со второго, идет с полученным ид сессии. На сервере периодически чистишь идешники сессий, скажем по принципу не было ни одного запроса с неким ид за некий таймаут. И получаешь некие своего рода датаграммы на TCP соединениях :) управляемые идентификаторами сессии :)
                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                  0 пользователей:


                                  Рейтинг@Mail.ru
                                  [ Script execution time: 0,0627 ]   [ 16 queries used ]   [ Generated: 28.04.24, 04:12 GMT ]