Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как грамотно организовать копирование файлов по локалке. (+) [D7, WinXP]


Страницы:   1 2

EarlVadim ©   (2006-01-18 10:42:00) 

Есть необходимость периодически опрашивать удалённые хосты (с доступом естессно) на наличие в сети, и в положительном случае, копировать с них определённый файл.

Сейчас тупо используеься COPYFILE(SFN,TFN); Проблема в том, что процесс копирования файла "примораживает" программу, а если хост недоступен, то это уже на 5-10 секунд "заморозка". Ни свернуть, ни закрыть, ничего.  Файл небольшой - до 100Кб.

Как это НАДО делать, чтобы процесс опроса-копирования действительно был ФОНОВЫМ?


EarlVadim   (2006-01-26 10:46:00) [1]

Да действительно, не PINGуется этот хост.
М-да FileExists о таких мелочах не волнуется.


Digitman   (2006-01-26 10:40:00) [2]

Это проблема с разрешением имени в IP-адрес - либо имя хоста неверно указано, либо на DNS-сервере отсутствует запись о хосте с указанным именем, либо проблемы в самой DNS-подсистеме


EarlVadim   (2006-01-26 10:11:00) [3]

Делаю так:

IdIcmpClient1.ReceiveTimeout:= 10000;
IdIcmpClient1.Port:= 80;
IdIcmpClient1.Host:= Edit1.Text;
IdIcmpClient1.Ping('',0);
Label1.Caption:= IdIcmpClient1.ReplyStatus.FromIpAddress;

Некоторые хосты возвращают IP-адрес, а некоторые говорят
Error #11001 Host not found.  Задолго то окончания TimeOut;


Digitman   (2006-01-26 09:30:00) [4]

Самый простой способ - использовать ICMP-клиента.

Например , компонент TIdICMPClient в составе Indy-пакета


EarlVadim   (2006-01-26 08:55:00) [5]


> Хосты в ЛВС имеют IP-адреса ?


Имеют.  Сеть MS на TCP/IP.


Digitman   (2006-01-26 08:35:00) [6]

Хосты в ЛВС имеют IP-адреса ?


EarlVadim   (2006-01-25 18:01:00) [7]


> т.е. тебе необходимо осуществить Packet INternet Gopher
> ...


Не уверен.

Мне надо передать некой функции имя хоста ( напр. \\SERVER ) и в качестве результата получить от неё TRUE - если SERVER в локальной сети присутствует.  
Второй момент,есть ли способы ускорить первоначальное обращение к файлам на удалённом компьютере. Дело в том, что если программа читает эти файлы с некоторой периодичностью, напр. раз в минуту, то первое чтение занимает существенно бОльшее время чем последующие. Не знаю причин этого, и возможно на это нельзя повлиять. Поэтому и спрашиваю.


Digitman   (2006-01-25 16:50:00) [8]

т.е. тебе необходимо осуществить Packet INternet Gopher ...


EarlVadim   (2006-01-25 16:35:00) [9]


> Дай свое определение термину "опрос хоста" ..


Наверное это PING.


Digitman   (2006-01-25 15:43:00) [10]


> меня сейчас напрягает больше вопрос именно касающийся сетей,
>  описанный мною выше


Дай свое определение термину "опрос хоста" ..


EarlVadim   (2006-01-25 15:31:00) [11]

Теперь понятно.
Ну это симпатичный код.
Только вопрос с ожиданием - он открыт.
Хотя можно попробовать SUSPEND и RESUME передавать.

Но меня сейчас напрягает больше вопрос именно касающийся сетей, описанный мною выше.    (EarlVadim ©   (25.01.06 12:53) [20]).


Digitman   (2006-01-25 15:15:00) [12]


> EarlVadim ©   (25.01.06 14:22) [25]
> FCommand и FResults
> Это переменные объявленные в private?


предположим - да...


> ProcessCommand это процедура с моим кодом?


опять же - например... т.е. - да ...


> что и откуда WaitCommand? какие значения может возвращать?


Это некий метод твоего класса TMyThread, который "приостанавливает" твой поток для ожидания "команд", ему адресованых ...

Он может возвращать некую команду, "посланную" потоку "извне" и которую данный поток должен исполнить.


EarlVadim   (2006-01-25 14:22:00) [13]

FCommand и FResults
Это переменные объявленные в private?
а ProcessCommand это процедура с моим кодом?
А что и откуда WaitCommand? какие значения может возвращать?


Digitman   (2006-01-25 14:05:00) [14]

А должен выглядеть хотя бы так :

while not Terminateddo begin
 FCommand := WaitCommand;
 if Terminated then Break;
 FResults := ProcessCommand(FCommand);
end;


Digitman   (2006-01-25 14:04:00) [15]

А должен выглядеть хотя бы так :

while not Terminateddo begin
 FCommand := WaitCommand;
 if Terminated then Break;
 FResults := ProcessCommand(FCommand);
end;


EarlVadim   (2006-01-25 13:54:00) [16]


> либо многократно


Да. Через определяемые в настройках программы промежутки времени.
Приоритет потока Thread.Priority := tpLowest;
А цикл в потоке у меня выглядит так

While true do
    If FCheck then BEGIN
       FCheck:= false;
       For i:= 0 to Lens-1 do FReady[i]:= false;
       For i:= 0 to Lens-1 do begin
           st:= TStringList.Create;
           try
                If FileExists(PChar(CF[i])+'\unitinfo.txt') then begin
                     st.LoadFromFile(PChar(CF[i])+'\unitinfo.txt');
                     FOutPar[i]:= ST.Strings[4];
                end else FOutPar[i]:= '';
           finally
                FReady[i]:= true;            
           end;
                st.free;
       end;
 END;


Digitman   (2006-01-25 13:14:00) [17]


> про красоту решения спорить не готов. Нормально это или
> нет?


Нет, не нормально.

Пустой цикл вида while Flag=False do;ощутимо отнимает процессорное время у других процессов и у других потоков того же процесса, не делая ничего полезного.

Да и нужно ли такое решение с циклами ?
Сомнительно.

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

Цикл в теле Execute (неважно какой, об этом - позже) напрашивается лишь при многократном использовании одного и того же объекта-потока.


EarlVadim   (2006-01-25 12:53:00) [18]


> Digitman ©   (25.01.06 11:28) [18]


И кстати, вопрос о том, как быстро опросить заданные хосты, на предмет их наличия в сети в данный момент. Я сейчас использую:

For i:= 0 to Len-1 do begin
    st:= TStringList.Create;
    try
        If FileExists(PChar(CF[i])+'\unitinfo.txt') then begin  // в CF:array of string - хранятся пути в виде "\\host1\path1"
           st.LoadFromFile(PChar(CF[i])+'\unitinfo.txt');
           FOutPar[i]:= ST.Strings[4];  
// это вывод результата тестовый - просто возвращается 4-я строка файла.
// На самом деле будет работа с данными файла намного насыщеннее
        end else FOutPar[i]:= '';
    finally
        FReady[i]:= true;
//  Установка флага о том, что этот сервер прочитан, основная прога
//  Ориентируется на него и забирает FOutPar не дожидаясь остальных
        st.free;
    end;
end;

Есть советы для меня?


EarlVadim   (2006-01-25 12:45:00) [19]


> Приводи полный код в последней своей редакции (неработающей)


:) Мне уже подсказали. Все дело в неверном месте вызова DESTROY;
Поток не устевает выполнится до EXECUTE когда основная программа вызывает DESTROY. Щас переписал код так, чтобы поток жил постоянно.
Просто пока параметром не пошлю TRUE - в теле EXECUTE выполняется пустой цикл. После выполнения EXECUTE флаг снова ставлю в FALSE и выполняю опять пустой цикл.
Вот про красоту решения спорить не готов. Нормально это или нет?

Но тебе отдельное спасибо за помощь в понимании основного принципа потоков и терпение к нам, "чайникам".


Digitman   (2006-01-25 11:28:00) [20]


> Может D7 глючит?


"Это вряд ли .." (с) Ф.Сухов

Приводи полный код в последней своей редакции (неработающей)


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо