![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как правильно остановить 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]Чем обоснован выбор именно Инди-компонентов ?