Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как правильно остановить IdTcpServer [D7, NT4, Win2k, WinXP]


Rav ©   (2007-10-30 13:16:00) 

Создал связь на основе Indy TcpServer-TcpClient. Все нормально, связь устанавливается, клиент отправляет команды, сервер их обрабатывает. Когда закрываешь программу-клиент, не закрывая соединения, сервер "правильно" реагирует, показывая завершение соединения со стороны клиента. А наоборот не работает! То есть, если просто закрыть программу-сервер или физически разовать связь (например выдернуть кабель), клиент никак не отрегирует на произошедшее. Да и сервер спустя какое-то время ругается на ошибку потока (я так понимаю серверный или клиентский поток продолжают работать и после завершения работы основной программы).
Собственно вопрос: как правильно закрыть клиентские соединения со стороны сервера перед его завершением, и если возможно, как отловить аварийное прерывание связи?
С сетевыми компонентами практически не работал, буду признателен за любые подсказки, в т.ч. ссылки на статьи, литературу.


umbra   (2007-11-01 16:05:00) [1]


> Сервер при этом занят блокирующим чтением.
>

и что? это же не значит, что сокет, выделенный для клиента нельзя закрыть. А если поток не завершается, значит он занят еще чем-то или в нем возникло исключение, которое не обработано. Скорее всего - в обработчике команды.


Сергей М.   (2007-11-01 15:26:00) [2]


> данные никакие не передаются


Сервер при этом занят блокирующим чтением.


Rav   (2007-11-01 14:58:00) [3]


> А чем же тогда занят поток ?)


А хто его знаить? :-)
Соединение "держит", но данные никакие не передаются.
Согласен, если бы в этот момент что-то передавалось, но...

Да ладно, Бог с ним, попробуем поковырять TTcpServer / TSocketServer


umbra   (2007-11-01 13:44:00) [4]

а лучше установите 10-й инди. Правда, тогда исходники придется править.


umbra   (2007-11-01 13:41:00) [5]

попробуйте увеличит значение свойства TerminateWaitTimeсервера.


Сергей М.   (2007-11-01 13:39:00) [6]


> в этот момент чтение/запись как раз и не идет


А чем же тогда занят поток ?)


Rav   (2007-11-01 13:09:00) [7]

И какже корректно прервать этот процесс?
Хотя в этот момент чтение/запись как раз и не идет (по крайней меря я ничего через него не передаю)


Сергей М.   (2007-11-01 12:34:00) [8]


> потоки вроде бы должны быть остановлены


С какого перепугу поток завершит выполнение, если он в момент команды терминирования занят блокирующим чтением/записью и, соответственно, не реагирует на команду ?


Rav   (2007-11-01 12:30:00) [9]

Если в OnClose формы НЕ ОСТАНАВЛИВАТЬ сервер (IdTcpServer.Active := False)
то ошибка следующая: "Exception EIdTerminateThreadTimeout in module.... Terminate Thread Timeout",
если в OnClose формы ОСТАНАНОВИТЬ сервер (IdTcpServer.Active := False)
то форма "зависает" и через какое-то время выдает ту же ошибку "Terminate Thread Timeout", но уже "штатно" не закрывается

Я покопался в исходниках с надыбал следующий код при остановке сервера
       TerminateListenerThreads;
       // Tear down ThreadMgr
       try
         TerminateAllThreads;
       finally
         if ImplicitThreadMgr and TIdThreadSafeList(Threads).IsCountLessThan(1) then begin // DONE -oAPR: BUG! Threads still live, Mgr dead ;-(
           FreeAndNil(FThreadMgr);
           FImplicitThreadMgr := False;
         end;
       end;//tryf
то есть, потоки вроде бы должны быть остановлены и все сокеты закрыты, но этого почему-то не происходит.


umbra   (2007-10-31 14:20:00) [10]


> > Вестимо как - превышение таймаута ожидания терминирования
> > созданных сервером транспортных потоков.
>
> И как лечить?
>


сервер что, так и пишет "превышение таймаута ожидания терминирования ...."?
Вы бы хоть класс исключения назвали.


Rav   (2007-10-31 12:15:00) [11]


> Исправить логические ошибки в OnExecute


Я не использовал обработчик OnExecute - только встроенный процессор команд. Пока.


Сергей М.   (2007-10-31 08:21:00) [12]


> как лечить?


Исправить логические ошибки в OnExecute


Slym   (2007-10-31 06:42:00) [13]

Rav   (30.10.07 21:54) [6]
И как лечить?

Примерно так:
try
 Sock.SendCmd
except
 Sock.Close;
end;


Rav   (2007-10-30 21:54:00) [14]


> Вестимо как - превышение таймаута ожидания терминирования
> созданных сервером транспортных потоков.

И как лечить?


Сергей М.   (2007-10-30 15:21:00) [15]


> umbra ©   (30.10.07 15:09) [4]



> как именно ругается?


Вестимо как - превышение таймаута ожидания терминирования созданных сервером транспортных потоков.


umbra   (2007-10-30 15:09:00) [16]


> То есть, если просто закрыть программу-сервер или физически
> разовать связь (например выдернуть кабель), клиент никак
> не отрегирует на произошедшее.

а откуда клиент может узнать, что кабель выдернули? Он узнает это только когда попытается послать серверу команду и не сможет.


> Да и сервер спустя какое-то время ругается на ошибку потока

А как именно ругается?


Сергей М.   (2007-10-30 15:01:00) [17]


> до конца и не смог разобраться с TTcpServer/TTcpClient


Что тебе там конкретно непонятно ?

И опять же - почему TTcpServer/TTcpClient ? Почему не TServerSocket/TClientSocket ? Почему не ICS-компоненты ?

И разве на встроенной обработке команд свет клином сошелся ? Что мешает реализовать собственную ?


> обработка команд идет в основном потоке, или в потоке клиента?


В дополнительном.


Rav   (2007-10-30 13:33:00) [18]


> Чем обоснован выбор именно Инди-компонентов ?


Во-первых, так до конца и не смог разобраться с TTcpServer/TTcpClient,... может кинете пару примеров работы с ними

Во-вторых, в Indy есть встроенная обработка команд, то что мне нужно.
Я только не понял, обработка команд идет в основном потоке, или в потоке клиента?


Сергей М.   (2007-10-30 13:20:00) [19]

Чем обоснован выбор именно Инди-компонентов ?


Наверх

Титульная страница Поиск, карта сайта Написать письмо