Конференция "Сети" » Проблема с ScktSrvr.exe [D7, WinXP]
 
  • Leo50 © (10.10.09 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?

    Заранее благодарен за ответы.
  • Сергей М. © (10.10.09 13:04) [1]

    > at address 0048B9F6


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

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

    см. меню IDE "Search -> Find Error .."
  • Leo50 © (10.10.09 16:33) [2]
    Дело в том, что ScktSrvr.exe поставляется вместе с Delphi. И я не силен в тонкостях работы сокетов, чтобы модифицировать его исходный код. Может быть есть какие-либо другие подходы? Или придется отказаться от применения SocketConnection.
  • Сергей М. © (10.10.09 16:47) [3]

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


    Приложение ScktSrvr поставляется с исходными текстами.
    Его, как и любое другое приложение, можно пересобрать со включенными отлад.опциями и запустить под управлением встр.отладчика, тогда меню IDE "Search -> Find Error .." поможет локализовать проблему, даже если ты не силен в тонкостях работы сокетов.
  • Сергей М. © (10.10.09 16:52) [4]

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


    Кр.того, в теле метода ConnectFile сокетами даже не пахнет.
  • Leo50 © (10.10.09 17:01) [5]
    Спасибо, Сергей М., за активную попытку мне помочь. Попробую еще повозиться. Дело в том, что исключение возникает не при выполнении ConnectFile, а при попытке его выполнения, т.е. до метода пройесс не доходит. Вторая проблема у меня в том, что раньше мне не приходилось отлаживать взаимодейтсвующие процессы из разных проектов. Пытаюсь это освоить. Но пока получаю только ассемблерный код, а до исходников не могу добраться. Буду биться дальше.
  • Сергей М. © (10.10.09 17:28) [6]

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


    Что значит "при попытке" ?
    Откуда ты узнал что при попытке, а не во время ?
  • Leo50 © (10.10.09 18:08) [7]
    При пошаговой отладке, когда все нормально, оператор  
    dmClient.SocketCon.AppServer.ConnectFile(FilePath)


    при нажатии F8 переходит на следующую строку кода. Когда возникает исключение от ScktSrvr, нажатие F8 не приводит к переходу к следующей строке. При этом параметр FilePath становится пустой строкой. Следующее нажатие F8 повторяет выполнение этого же оператора. Из этого я и решил, что до самого метода процесс не доходит. Кстати непосредственно перед возникновением ошибки, пропадает доступ к AppServer.
  • Сергей М. © (10.10.09 19:11) [8]
    А scktsrvr.exe при этом работает на той же самой машине ?
  • Leo50 © (10.10.09 19:33) [9]
    Сейчас пробую все на одной машине. Но пробовал и в сети, когда на каждом сервере приложений свой scktsrvr.exe. Клиент пытается опрашивать все серверы, но картина получается такая же, та же ошибка.
  • Leo50 © (11.10.09 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;



    Объяснить это могу только тем, что параметры, используемые в методах интерфеса видимо должны быть локальными.
  • Сергей М. © (11.10.09 17:41) [11]
    Ерунда какая-то ..
  • Leo50 © (11.10.09 21:45) [12]
    В том-то и дело, что ерунда какая-то, но работает. Спасибо, Сергей М., за помощь.
  • Сергей М. © (12.10.09 10:06) [13]

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


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

    Метод GetBDFiles у тебя ожидает формальным параметром тип WideString, а ты ему впариваешь тип TStringList ..
  • Leo50 © (12.10.09 15:57) [14]

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

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


    Кстати, как в исходном вопросе, так и в работающем варианте пропущена строка
    FilePath:=FacBDFiles.ValueFromIndex[i];


    которая выполняется непосредственно перед обращением к методу
    dmClient.SocketCon.AppServer.ConnectFile(FilePath);

  • Leo50 © (12.10.09 16:08) [15]
    Извините, поторопился, нажал не те клавиши. В предыдущем сообщении не патасетр, а параметр. В следующий раз буду внимательнее. Как исправить уже отправленное сообщение, не знаю.
  • Сергей М. © (12.10.09 16:24) [16]
    А, ну да ..
    Пардон, параметр передается действительно требуемого типа.

    Ну тогда еще одно замечание (не связанное непосредственно с проблемой) - нет никакой нужды чистить (Clear) стринглист сразу после его создания, он создается уже пустым.
  • Leo50 © (12.10.09 16:30) [17]
    Спасибо, Сергей М., за совет. Сидит во мне какой-то синдром перестраховки, поэтому на всякий случай и чищу стринглист. На будущее учту.
 
Конференция "Сети" » Проблема с ScktSrvr.exe [D7, WinXP]
Есть новые Нет новых   [134437   +29][b:0][p:0.002]