Форум: "Сети";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.25;
Скачать: [xml.tar.bz2];




Вниз

Как работать с TNMStrm на подтверждение чего-либо? 


Aleksandr   (2002-02-13 13:45) [0]

После долгих переборов разных компонент на прием/отправку информации решил я остановиться на TNMStrmServ (принимающий) TNMStrm (отправляющий). У меня две копии программы на разных компьютерах - при нахождении определенных файлов они отправляют эти файлы с помощью TNMStrm.PostIt своей "напарнице". Все просто и красиво... Только вот есть проблема - эти файлы принявшая программа обрабатывает (тем временем отославшая должна ждать флага, что все ок), и в случае проблемы с обработкой она должна послать программе-отправителю флаг, что файл не следует считать отправленным и удалять... И вроде есть свойство у TNMStrm OnRead, только вот его не присобачить стандартными путями типа NMStream.OnRead:=FNMStreamOnRead, и документации никакой нормальной по сим компонентам (а для меня эта область - вообще знакомы три дня)... Может, кто-нибудь в курсе, как это оформить?



Digitman (M)   (2002-02-13 14:07) [1]

>>"присобачить стандартными путями"
это как, по-твоему ?



Aleksandr   (2002-02-13 14:12) [2]

"Стандартными путями" - это:
...
private
FNMStream : TNMStrm;
procedure FNMStreamOnRead(Sender : TObject);
...

constructor TWebDataProcessor.Create...
begin
FNMStream:=TNMStrm.Create(nil);
FNMStream.OnRead:=FNMStreamOnRead;
...

В упор ни сервер ни клиент не заглядывают в эти процедуры чтения...



Digitman (M)   (2002-02-13 14:20) [3]

ну, с клиентом-то, положим, еще вопрос открытый, а вот сервер-то - с какого перепугу будет в чужое событие "заглядывать" ? Событие TNMStrm.OnRead, согласно описанию, "... is called when there is incoming data being sent from the remote host."
"remote host" для TNMStrm - это TNMStrmServ. Этот самый TNMStrmServ хоть что-то being sent ему, TNMStrm"у ?



Aleksandr   (2002-02-13 14:26) [4]

Он-то отправляет, а вот принять - никак... Мало того, в подобным образом присвоенную OnMsg он тоже не заглядывает, если данные были отправлены не PostIt, а Writeln... Дык если у TNMStrmServ доступна пропертя OnRead, чего бы и не читать? Или уж разработчикам убирать его надо было, чтоб людев не путать... Интересно, какое событие у него тогда происходит...



Digitman (M)   (2002-02-13 14:45) [5]

Дык у TNMStrmServ "случается" TNMStrmServ.OnRead, а у TNMStrm - TNMStrm.OnRead ! Ведь совершенно разные объекты ! В частном случае - разные адресные пространства, да и разные машины) Это как бы ты осознаешь ?



Aleksandr   (2002-02-13 15:00) [6]

Видимо, неясно объяснил... Разумеется, эти объекты у меня являются пропертями в совершенно разных объектах, и у каждого свой метод на чтение... Я же не одну процедуру им присваиваю - для каждого своя!



Digitman (M)   (2002-02-13 15:11) [7]

>Aleksandr
Вот именно - "неясно") И будет еще много "неясностей" до тех пор, пока код приема/передачи сервера и код приема/передачи клиента не приведешь



Aleksandr   (2002-02-13 16:01) [8]

2 Digitman
Ок, даю код:
// модуль с потоком-отсыльщиком данных
type
TDataStatus=(dsIdle,dsCommand);

TWebDataProcessor=class (TThread)
private
...
FNMStream : TNMStrm;
FStatus : TDataStatus;
public
constructor Create(ACreateSuspended : boolean;
ASleepInterval : longint;ADir : string;
AHost : string; APort : word);
procedure Execute; override;
function SendFile(AFileName : string) : boolean;
procedure FNMStreamOnRead(Sender : TObject);
...
end;

var
Section : TRTLCriticalSection;

implementation

...
constructor TWebDataProcessor.Create(ACreateSuspended : boolean;
ASleepInterval : longint;ADir : string;
AHost : string; APort : word);
begin
inherited Create(true);
FreeOnTerminate:=False;
FSleepInterval:=ASleepInterval;
FDir:=ADir;
FNMStream:=TNMStrm.Create(nil);
FNMStream.Host:=AHost;
FNMStream.Port:=APort;
FNMStream.OnRead:=FNMStreamOnRead;
FlogCount:=1000;
FStatus:=dsIdle;
FLogFile:=CorrectPath(LogFilesDir)+"nmstream.log";
InitializeCriticalSection(Section);
if NOT ACreateSuspended then
Resume
end;

procedure TWebDataProcessor.Execute;
var
HeadersList : TList;
FData : PWin32FindData;
i : integer;
s : string;
begin
while NOT Terminated do begin
HeadersList:=TList.Create;
if SearchFiles32(HeadersList,FDir+HeadersMask) then begin
for i:=0 to HeadersList.Count-1 do begin
FData:=HeadersList.Items[i];
EnterCriticalSection(Section);
if FileExists(CorrectPath(FDir)+ExtractFileName(FData.cFileName)) AND SendFile(CorrectPath(FDir)+ExtractFileName(FData.cFileName)) then begin
s:=CorrectPath(FDir)+ExtractFileName(FData.cFileName);
AddLog("header sended: "+s)
end;
LeaveCriticalSection(Section);
Dispose(Fdata)
end
end;
HeadersList.Free;
Sleep(FSleepInterval)
end
end;

function TWebDataProcessor.SendFile(AFileName: string): boolean;
var
R : TRiHeader;
F : TFileStream;
begin
Result:=false;
R:=TRIHeader(GetFromFileStream(AFileName));
try
if FileExists(R.TransName) then begin
F:=TFileStream.Create(R.TransName,fmOpenRead);
try
FNMStream.FromName:=ExtractFileName(R.TransName);
FNMStream.PostIt(F);
FStatus:=dsCommand;
FNMStream.TimeOut:=5000;
FNMStream.Connect;
if FNMStream.Connected then begin
FNMStream.Writeln("OK");
while (FStatus=dsCommand) OR FNMStream.BeenTimedOut do
Application.ProcessMessages;
FNMStream.DisConnect;
end;
FNMStream.TimeOut:=0;
if (NOT FNMStream.BeenTimedOut) AND (FStatus=dsIdle) then
Result:=true;
except
on E:Exception do
AddLog(E.Message)
end
end
finally
if Assigned(F) then
F.Free;
if Result then begin
DeleteFile(AFileName);
DeleteFile(R.TransName)
end;
R.Free
end
end;

procedure TWebDataProcessor.FNMStreamOnRead(Sender: TObject);
begin
if FStatus=dsCommand then
FStatus:=dsIdle
end;

//Код из программы-клиента в создании формы:
FDataProcessor:=TWebDataProcessor.Create(false,500,....,80);
//Код из тестировочной программы-сервера:

type
TForm1 = class(TForm)
lbMessages: TListBox;
NMStrmServ1: TNMStrmServ;
procedure NMStrmServ1MSG(Sender: TComponent; const sFrom: String;strm: TStream);
procedure FormCreate(Sender: TObject);
...
private
FStatus : TDataStatus;
public
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.NMStrmServ1MSG(Sender: TComponent; const sFrom: String;
strm: TStream);
var
F : TMemoryStream;
begin
if FStatus=dsIdle then begin
F:=TMemoryStream.Create;
F.CopyFrom(Strm,NMStrmServ1.BytesTotal);
F.SaveToFile(OutDir+sFrom);
F.Free;
FStatus:=dsCommand;
lbMessages.Items.Add("Received "+sFrom)
end
else begin
NMStrmServ1.Writeln("OK!");
lbMessages.Items.Add("Executing - OK ");
FStatus:=dsIdle
end
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Fstatus:=dsIdle;
NMStrmServ1.Connect
end;



Polevi   (2002-02-13 17:23) [9]

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



Digitman (M)   (2002-02-13 17:41) [10]

все ясно)
рассуждай вслух, я веду тебя к решению проблемы !
комментируй свой код :

procedure TForm1.FormCreate(Sender: TObject);
begin
Fstatus:=dsIdle;
NMStrmServ1.Connect // что здесь происходит по-твоему ? кто с кем пытается соединится ?
end




Форум: "Сети";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.04.25;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.75 MB
Время: 0.043 c
1-80935           Sniffer               2002-04-11 17:36  2002.04.25  
Народ хелп плз


3-80799           Марина                2002-04-05 09:11  2002.04.25  
Table is busy.User:???


1-80922           shane54               2002-04-11 00:17  2002.04.25  
Вопрос по таймеру


14-81034          MBo                   2002-03-18 16:13  2002.04.25  
определить адрес процедуры из нее самой


14-81074          Serd_hhc              2002-03-21 11:39  2002.04.25  
Ну помогите же, пожалуйста