Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > проверка состояния соединения


Автор: Anden 1.7.2010, 06:34
Здравствуйте Всем!!! Возникла следующая проблема: в определенный момент времени приложение работающее с базой  microsoft sql server теряет связь кратковременно и выходят ошибки бесконца пока не перезапустишь приложение. Вопрос: Как можно проконтролировать состояние соединения чтобы можно было  предупредить появление данной ошибки????

Заранее Всем очень благодарен!!!!

Автор: mrbrooks 1.7.2010, 07:51
если используете ADO изучите события ADOConnection 

Автор: Anden 1.7.2010, 11:54
Цитата(mrbrooks @ 1.7.2010,  07:51)
если используете ADO изучите события ADOConnection

ну вродь изучал но чего то не нашел как проверить состояние соединения, т.е. есть связь с сервером или ее нету. Сетка WI-FI с направленой антеной на 12 км.ьСервак ноходиться в 5 км от клиентского компа.

Автор: Anden 5.7.2010, 16:22
блин никто мне помочь не может чтоли???? smile  замучался уже

Автор: t4aynik 5.7.2010, 17:59
Как спросили, так и ответ получили. вы ж ничего не написали, как у вас что реализовано.... Ошибки  вылазят в цикле, знацца какойто цикл крутится пока какаято функция не получит/отправит данные, причем ошибки этой функции не обрабатываются.  Вот вам и надо найти этот цикл и функцию получения/отправки данных, и сделать там что-нибудь. Если нет функций проверки, так может можно ее в ексцепшен запихнуть? а в кетче сделать ну например реконнект, или сделать признак для дальнейшего реконнекта после выхода из ексцепшна. а сетка не важно какая вайфай или диалап, вы ж не на канальном уровне работаете...

Автор: _Dimon_ 5.7.2010, 19:13
Цитата(t4aynik @  5.7.2010,  17:59 Найти цитируемый пост)
Ошибки  вылазят в цикле, знацца какойто цикл крутится пока какаято функция не получит/отправит данные, причем ошибки этой функции не обрабатываются.  Вот вам и надо найти этот цикл и функцию получения/отправки данных, и сделать там что-нибудь.



Не обязательно в цикле. Дело в том что у меня в проге тоже такая муть, хотя я использую другой сервер бд (ADS), при дисконекте куча ошибок мол открыта такая-то таблица. У меня есть событие OnDisconnect. Неважно что я там напишу, всеравно вылазят эти ошибки.

Это наверно черз то что открытые датасеты и датасорсы. При дискоконнекте прога как-бы подвисает - а потом эти гребаные сообщения.

Автор: t4aynik 6.7.2010, 09:46
Так а через что вы коннектитесь? ОДБЦ?

Автор: A5uKa 6.7.2010, 09:53
Цитата

как проверить состояние соединения, т.е. есть связь с сервером или ее нету


у меня была идея их пинговать  smile 

Код

                if(FormCllient->ReadString("Servers","s"+String(z),"")=="")
                        break;
                else
                {

                        temp=FormCllient->ReadString("Servers","s"+String(z),"");
                        temp.Delete( (temp.Pos('\\') ) , ( temp.Length()-temp.Pos('\\')+1 ) );
                        Indy->Host=temp;
                        try
                        {
                                Indy->ReceiveTimeout=500;
                                Indy->Ping();
                        if (Indy->ReplyStatus.BytesReceived!=0)
                        ConParms->ServComboBox->Items->Add(FormCllient->ReadString("Servers","s"+String(z),""));
                        }
                        catch(EIdSocketError &exc)
                        {
                                if (exc.LastError == 11001);// ShowMessage("Ñåðâåð íå îòâå÷àåò! Áëàáëàáëà");
                                else  ShowMessage("Socket error");
                        }
                }

Автор: t4aynik 6.7.2010, 10:32
Я с инди не занимался. Это что за пинг, собственно передача ICMP пакетов или передача тестовых пакетов по рабочему соединению?

Автор: A5uKa 6.7.2010, 10:36
Цитата(t4aynik @ 6.7.2010,  10:32)
Я с инди не занимался. Это что за пинг, собственно передача ICMP пакетов или передача тестовых пакетов по рабочему соединению?

Понятия не имею  smile 

Автор: t4aynik 6.7.2010, 11:28
Ну и что вы после этого хотите тогда?  smile

Автор: A5uKa 6.7.2010, 11:35
Цитата(t4aynik @ 6.7.2010,  11:28)
Ну и что вы после этого хотите тогда?  smile

ну пинг то работает )

Автор: Anden 6.7.2010, 12:54
Цитата(t4aynik @ 6.7.2010,  09:46)
Так а через что вы коннектитесь? ОДБЦ?

ADOConnect с базой  через ADOQuery

Добавлено через 1 минуту и 38 секунд
Цитата(t4aynik @ 6.7.2010,  11:28)
Ну и что вы после этого хотите тогда?  smile

вопрос в том что если связь один раз разорвалась на секунду то она больше не востановиться до перезапуска приложения а только будут безсконца выходить ошибки об отсуствие сервака с таким именем

Автор: chaos 6.7.2010, 13:25
Цитата(Anden @  6.7.2010,  09:54 Найти цитируемый пост)
она больше не востановиться до перезапуска приложения а только будут безсконца выходить ошибки об отсуствие сервака с таким именем

дак надо делать "реконект". в вашем случае вы его делаете перезапуском приложения

Автор: t4aynik 6.7.2010, 14:54
Цитата(Anden @  6.7.2010,  12:54 Найти цитируемый пост)
вопрос в том что если связь один раз разорвалась на секунду то она больше не востановиться до перезапуска приложения а только будут безсконца выходить ошибки об отсуствие сервака с таким именем

вот все ваши обращения к базе данных запихнуть в try{}, а в catch(){} нужно чтото сделать, что думайте сами, смотря как у вас там сделано.  Не знаю как в АДО сделать разрыв сессии, может вам просто ->Close() поможет. В простом ODBC можно сделать Query->DBSession->Close(), это разрывает текущуюю сессию с базой (Query->Close() этого не делает),  что позволяет в дальнейшем сделать заново соединение с базой без перезапуска программы. Может еще есть способы, меня устраивает этот. По идее вам нужно найти аналогичный способ. 

Автор: 0x00 23.7.2010, 08:12
У oracloвских компонент есть beforedisconnect событие, посмотрите может и в ADO они есть, посоветовал бы смотреть в их сторону.

Автор: mrbrooks 23.7.2010, 08:58
народ. читайте документацию. я это еще во втором посте написал.

http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/!!MEMBERTYPE_Events_ADODB_TADOConnection.html

Цитата(0x00 @  23.7.2010,  09:12 Найти цитируемый пост)
У oracloвских компонент есть beforedisconnect событие, посмотрите может и в ADO они есть, посоветовал бы смотреть в их сторону. 


у них у всех папа с мамой один. конечно же есть.

Автор: t4aynik 23.7.2010, 12:15
Цитата(0x00 @  23.7.2010,  08:12 Найти цитируемый пост)
У oracloвских компонент есть beforedisconnect событие, посмотрите может и в ADO они есть, посоветовал бы смотреть в их сторону.

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

Автор: mrbrooks 23.7.2010, 12:21
Цитата(t4aynik @  23.7.2010,  13:15 Найти цитируемый пост)
а само приложение не видит что коннект потерян

поясни?

Автор: t4aynik 26.7.2010, 17:15
допустим связано два компа, не напрамую кабелями а например через два коммутатора. Когда они непрерывно передают данные друг другу то тут все понятно, соединение пропало ошибка передачи данных. Если рвется коннект между компом и коммутатором, в частности физически, тоже более менее просто - ОС чаще всего видит проблему как отключение кабеля (частность). А вот если проблема на линии случилась гдето между коммутаторами, как операционка и приложение узнают что случилась беда? пока не будут переданы какие либо данные никто ничего не узнает. т.е. фактически коннект разорван, а никакого события а ля OnDisconnect не случится. И мы получаем все ту же ошибку при отсылке данных. Которую мы должны корректно отработать - перехватить в исключении и сделать разрыв/уничтожение текущего соединения, и создать его заново. Сторона которая должна получать данные в этом плане проигрывает - т.к. об ошибке она может так просто не узнать. Для таких проблем умные люди придумали keep alive - служебные пакеты, что передаются операционкой автоматически раз в заданный переиод простоя соединения, с дальнешими попытками восстановления соединения при возникновении проблемы. Если восстановить не получилось - передает приложению ошибку, чтоб то не потело, не мучалось и не ждало свой таймаут. (в винде по дефолту отключено) Это общая идея для сокетов. 
В плане соединений БД почти никаких отличий вроде как нет - то же сокет соедние, только спрятанное в средства работы с БД, кроме как поддержки keep alive средствами БД, но вроде как далеко не везде.  Засим предлагаю еще раз запихнуть все ваши обращения к БД в исключения. Так будет надежнее всего, даже есть есть какие-нибудь средства для контроля состояния коннекта, вы будет сами контролировать все проблемы с соединением. 
ЗЫ.: В билдере по дефолту появляется сообщение об ошибке даже если она произошла в исключении, это отключаемо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)