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

Вниз

Проблема с ScktSrvr.exe   Найти похожие ветки 

 
Leo50 ©   (2009-10-10 09:46) [0]

Уважаемые специалисты! Нужна помощь. Delphi 7. Трехзвенная архитектура.
Сервер приложений - RemoteDateModule, клиент - SocketConnection.    

 Краткое описание системы: Имеется несколько деканатов. В деканате может быть несколько
компьютеров, на которых установлены серверы приложений на основе RemoteDateModule
(например, свой компьютер на каждую форму обучения).
Кроме того, один сервер приложений может соединяться с несколькими файлами БД
(например, для каждой группы специальностей свой файл БД). В качестве БД используется
FireBird. Пути к доступным файлам БД хранятся в ini-файле.
  Клиент (учебный отдел, проректор и т.п.) имеет свою локальную БД, в которую
записываются различные сводные данные, импортируемые с факультетов.
В этой БД имеются также данные о компьютерах факультетов (IP-адреса и т.п.).
Для соединения с сервером приложений используется SocketConnection.

 Задача в следующем. Необходимо реализовать импорт данных со всех компьютеров
и со всех доступных файлов БД факультета.
 Вариант решения: Из локальной БД клиента запрос (компонент DSetComps) предоставляет
список компьютеров факультета. С каждым компьютером по очереди выполняется соединение
и запрашивается список доступных файлов БД (метод интерфеса GetBDFiles). Затем поочередно
с помощью метода ConnectFile серверу передается путь к файлу БД, из которого
надо импортировать данные. ConnectFile записывает этот путь в соответствующее свойство
компонента IBDatabase.

Фрагмент кода тонкого клиента:

var
 BDFiles,FilePath:WideString;
 FacBDFiles:TStringList;
begin
...

 dmLocalBD.DSetComps.First;
 while not dmLocalBD.DSetComps.Eof do
 begin
   dmClient.SocketCon.Close;
   dmClient.SocketCon.Address:=dmLocalBD.DSetCompsIPADDR.AsString;
   try
     FacBDFiles:=TStringList.Create;
     FacBDFiles.Clear;
     dmClient.SocketCon.AppServer.GetBDFiles(BDFiles);
     FacBDFiles.Text:=BDFiles;
   except
     ...
   end;
   for i:=0 to FacBDFiles.Count-1 do
   begin
     try
       dmClient.SocketCon.AppServer.ConnectFile(FilePath);
       ImpData; //Импорт данных
     except
       ...
     end;
   end;
   dmLocalBD.DSetComps.Next;
 end;
 dmClient.SocketCon.Close;
end;


Методы интерфейса сервера приложений:

procedure TAppServerDec.GetBDFiles(out BDFiles: WideString);
var
 Lst:TStringList;
 IniFile:TMemIniFile;
begin
 Lst:=TStringList.Create;
 Lst.Clear;
 IniFile:=TMemIniFile.Create(ExtractFilePath(Application.ExeName)+"Decanat.ini");
 IniFile.ReadSectionValues("RemoteAccess",Lst);
 BDFiles:=Lst.Text;
 Lst.Free;
 IniFile.Free;
end;

procedure TAppServerDec.ConnectFile(const FilePath: WideString);
begin
 if IBDatabase.Connected
   then IBDatabase.Close;
 IBDatabase.DatabaseName:=FilePath;
end;


Проблема в следующем. Импорт с первого компьютера происходит норамально.
При переходе ко второму компьютеру метод GetBDFiles тоже успешно передает
список БД, а вот при выполнении метода ConnectFile возникает исключительная
ситуация со следующим сообщением:
 Project raised exception class Exception with message "Access violation
at address 0048B9F6 in module "ScktSrvr.exe". Read of address 00000000.

Это моя ошибка или глюк в ScktSrvr.exe, поскольку с DCOMConnection
все работает норамально? Как это все исправить для SocketConnection?

Заранее благодарен за ответы.


 
Сергей М. ©   (2009-10-10 13:04) [1]


> at address 0048B9F6


Этот адрес указывает на вполне определенную строчку исх.текста приложения scktsrvr.exe.

Воспользуйся встр.отладчиком для локализации строчки-источника исключения

см. меню IDE "Search -> Find Error .."


 
Leo50 ©   (2009-10-10 16:33) [2]

Дело в том, что ScktSrvr.exe поставляется вместе с Delphi. И я не силен в тонкостях работы сокетов, чтобы модифицировать его исходный код. Может быть есть какие-либо другие подходы? Или придется отказаться от применения SocketConnection.


 
Сергей М. ©   (2009-10-10 16:47) [3]


> ScktSrvr.exe поставляется вместе с Delphi


Приложение ScktSrvr поставляется с исходными текстами.
Его, как и любое другое приложение, можно пересобрать со включенными отлад.опциями и запустить под управлением встр.отладчика, тогда меню IDE "Search -> Find Error .." поможет локализовать проблему, даже если ты не силен в тонкостях работы сокетов.


 
Сергей М. ©   (2009-10-10 16:52) [4]


> при выполнении метода ConnectFile возникает исключительная
> ситуация


Кр.того, в теле метода ConnectFile сокетами даже не пахнет.


 
Leo50 ©   (2009-10-10 17:01) [5]

Спасибо, Сергей М., за активную попытку мне помочь. Попробую еще повозиться. Дело в том, что исключение возникает не при выполнении ConnectFile, а при попытке его выполнения, т.е. до метода пройесс не доходит. Вторая проблема у меня в том, что раньше мне не приходилось отлаживать взаимодейтсвующие процессы из разных проектов. Пытаюсь это освоить. Но пока получаю только ассемблерный код, а до исходников не могу добраться. Буду биться дальше.


 
Сергей М. ©   (2009-10-10 17:28) [6]


> при попытке его выполнения


Что значит "при попытке" ?
Откуда ты узнал что при попытке, а не во время ?


 
Leo50 ©   (2009-10-10 18:08) [7]

При пошаговой отладке, когда все нормально, оператор  
dmClient.SocketCon.AppServer.ConnectFile(FilePath)
при нажатии F8 переходит на следующую строку кода. Когда возникает исключение от ScktSrvr, нажатие F8 не приводит к переходу к следующей строке. При этом параметр FilePath становится пустой строкой. Следующее нажатие F8 повторяет выполнение этого же оператора. Из этого я и решил, что до самого метода процесс не доходит. Кстати непосредственно перед возникновением ошибки, пропадает доступ к AppServer.


 
Сергей М. ©   (2009-10-10 19:11) [8]

А scktsrvr.exe при этом работает на той же самой машине ?


 
Leo50 ©   (2009-10-10 19:33) [9]

Сейчас пробую все на одной машине. Но пробовал и в сети, когда на каждом сервере приложений свой scktsrvr.exe. Клиент пытается опрашивать все серверы, но картина получается такая же, та же ошибка.


 
Leo50 ©   (2009-10-11 15:47) [10]

Проблему решил. Если кто столкнется с такой ситуацией, данное решение может пригодиться (возможно и не самое идеальное, но все работает нормально).
  Обращения к методам интерфейса включил в специальные процедуры, в которых параметры BDFiles и FilePath локальные.

procedure GetSpDBFiles(var Files:TStringList);
var
 BDFiles:WideString;
begin
 dmClient.SocketCon.AppServer.GetBDFiles(BDFiles);
 Files.Text:=BDFiles;
end;

procedure SetFilePath(FilePath:WideString);
begin
 dmClient.SocketCon.AppServer.ConnectFile(FilePath);
end;


Вместо обращения к методам интерфейса

dmClient.SocketCon.AppServer.GetBDFiles(BDFiles)
dmClient.SocketCon.AppServer.ConnectFile(FilePath);


реализовал обращение к соответствующим процедурам

GetSpDBFiles(FacBDFiles)
SetFilePath(FilePath)


В результате получается следующий фрагмент
кода:

var
 FilePath:WideString;
 FacBDFiles:TStringList;
begin
...

 dmLocalBD.DSetComps.First;
 while not dmLocalBD.DSetComps.Eof do
 begin
   dmClient.SocketCon.Close;
   dmClient.SocketCon.Address:=dmLocalBD.DSetCompsIPADDR.AsString;
   try
     FacBDFiles:=TStringList.Create;
     FacBDFiles.Clear;
     GetSpDBFiles(FacBDFiles);
   except
     ...
   end;
   for i:=0 to FacBDFiles.Count-1 do
   begin
     try
       SetFilePath(FilePath);
       ImpData; //Импорт данных
     except
       ...
     end;
   end;
   dmLocalBD.DSetComps.Next;
 end;
 dmClient.SocketCon.Close;
end;


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


 
Сергей М. ©   (2009-10-11 17:41) [11]

Ерунда какая-то ..


 
Leo50 ©   (2009-10-11 21:45) [12]

В том-то и дело, что ерунда какая-то, но работает. Спасибо, Сергей М., за помощь.


 
Сергей М. ©   (2009-10-12 10:06) [13]


> Импорт с первого компьютера происходит норамально.
> При переходе ко второму компьютеру метод GetBDFiles тоже
> успешно передает


Как это вообще работало - уму не постижимо)

Метод GetBDFiles у тебя ожидает формальным параметром тип WideString, а ты ему впариваешь тип TStringList ..


 
Leo50 ©   (2009-10-12 15:57) [14]


> Метод GetBDFiles у тебя ожидает формальным параметром тип
> WideString, а ты ему впариваешь тип TStringList ..

Почему TStringList? Патасетр объявлен как WideStrig:
var
BDFiles:WideString;

Кстати, как в исходном вопросе, так и в работающем варианте пропущена строка
FilePath:=FacBDFiles.ValueFromIndex[i];
которая выполняется непосредственно перед обращением к методу
dmClient.SocketCon.AppServer.ConnectFile(FilePath);


 
Leo50 ©   (2009-10-12 16:08) [15]

Извините, поторопился, нажал не те клавиши. В предыдущем сообщении не патасетр, а параметр. В следующий раз буду внимательнее. Как исправить уже отправленное сообщение, не знаю.


 
Сергей М. ©   (2009-10-12 16:24) [16]

А, ну да ..
Пардон, параметр передается действительно требуемого типа.

Ну тогда еще одно замечание (не связанное непосредственно с проблемой) - нет никакой нужды чистить (Clear) стринглист сразу после его создания, он создается уже пустым.


 
Leo50 ©   (2009-10-12 16:30) [17]

Спасибо, Сергей М., за совет. Сидит во мне какой-то синдром перестраховки, поэтому на всякий случай и чищу стринглист. На будущее учту.



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

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

Наверх




Память: 0.52 MB
Время: 0.006 c
15-1323898980
ffff
2011-12-15 01:43
2012.04.22
Напомните, плиз, о гениальных изобретениях ближайшего прошлого :)


2-1325109344
TThread
2011-12-29 01:55
2012.04.22
TPotok_Com.Terminate


2-1324830541
Wanderer
2011-12-25 20:29
2012.04.22
Writefile, TList и динамические переменные


15-1323982683
Германн
2011-12-16 00:58
2012.04.22
Странный глюк с поисковыми запросами.


2-1325272121
Псарь
2011-12-30 23:08
2012.04.22
Как написать инспектор объектов?