Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.10.12;
Скачать: CL | DM;

Вниз

Как правильно остановить IdTcpServer   Найти похожие ветки 

 
Rav   (2007-10-30 13:16) [0]

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


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

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


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


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


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

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


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


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


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

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

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


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


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


 
umbra ©   (2007-10-30 15:09) [4]


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

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


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

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


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


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



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


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


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


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

И как лечить?


 
Slym ©   (2007-10-31 06:42) [7]

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

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


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


> как лечить?


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


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


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


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


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


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


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


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

Если в 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
то есть, потоки вроде бы должны быть остановлены и все сокеты закрыты, но этого почему-то не происходит.


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


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


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


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

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


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


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


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


 
umbra ©   (2007-11-01 13:41) [15]

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


 
umbra ©   (2007-11-01 13:44) [16]

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


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


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


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

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


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


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


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


 
umbra ©   (2007-11-01 16:05) [19]


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

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



Страницы: 1 вся ветка

Текущий архив: 2008.10.12;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.018 c
2-1220262994
gln
2008-09-01 13:56
2008.10.12
Прокрутка RichEdit


2-1220106974
Alral
2008-08-30 18:36
2008.10.12
Функция Recv и PChar


15-1219565619
Kostafey
2008-08-24 12:13
2008.10.12
С днем рождения ! 24 августа


15-1219404029
cyborg
2008-08-22 15:20
2008.10.12
TDataGrid


2-1220887663
Terasbetoni
2008-09-08 19:27
2008.10.12
Использование двух классов друг другом. Классы в разных модулях