Форум: "Сети";
Текущий архив: 2008.10.12;
Скачать: [xml.tar.bz2];
ВнизКак правильно остановить 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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.044 c