I'm need send a strem from TCPClient to TCPServer,
Try this but don't work:
Server side;
with AThread.Connection do begin
sCommand := ReadLn;
if SameText(cOPY(sCommand, 1, 6), 'UPLOAD') then begin
stream:=Tmemorystream.create;
ReadStream(stream);
stream.SaveToFile(filename);
stream.free; end;
Client side:
stream:=TmemoryStream.create;
IdTCPClient1.host:=Ehostname.text;
IdTCPClient1.connect;
memo1.clear;
Try
Memo1.lines.Add(IdTCPClient1.ReadLn);
IdTCPClient1.writeLn('UPLOAD'+FilenameEdit1.TEXT);
while IdTCPClient1.connected do
begin
IdTCPClient1.OpenWriteBuffer;
IdTCPClient1.WriteStream(stream);
IdTCPClient1.CloseWriteBuffer;
stream.free;
IdTCPClient1.disconect;
thanks in advance
Bruno
The example show how send a stream from server to client, I need make
contrary, send stream from client to server.
thanks
sending a stringlist from the client
sl is TStringList
ms is TMemoryStream
comando is integer
sRetorno is string
ID_PROCESSAR is one of my consts
// Enviar o que foi processado
if sl.count > 0 then begin
ms := TMemoryStream.Create;
sl.SaveToStream( ms );
FreeAndNil(sl);
TCPClient.WriteLn( FormatFloat('00',ID_PROCESSA_SIZE) +
IntToStr(ms.size) );
sRetorno := TCPCLient.ReadLn;
comando := StrToInt( copy(sRetorno,1,2) );
sRetorno := copy(sRetorno,3,length(sRetorno)-2);
if comando = ID_PROCESSAR then begin
ms.position := 0;
TCPClient.OpenWriteBuffer;
TCPClient.WriteStream(ms);
TCPClient.CloseWriteBuffer;
end;
FreeAndNil(ms);
end;
at server side
str is string
comando and Processa_Size are integer
ID_PROCESSA_SIZE and ID_PROCESSAR are consts
str := uppercase(AThread.Connection.ReadLn);
comando := StrToInt(copy(str,1,2));
str := copy(str,3,length(str)-2);
case comando of
ID_PROCESSA_SIZE:
begin
try
Processa_Size := StrToInt(str);
except
Processa_Size := 0;
end;
if Processa_Size > 0 then begin
AThread.Connection.WriteLn( FormatFloat('00',ID_PROCESSAR) );
if ms <> nil then FreeAndNil(ms);
ms := TMemoryStream.Create;
AThread.Connection.ReadStream(ms,Processa_Size,false);
sl := TStringList.Create;
ms.position := 0;
sl.LoadFromStream(ms);
FreeAndNil(ms);
ProcessarEmprestimosPendentes(sl); // My function, you don't need
FreeAndNil(sl);
end;
end;
end;
Bruno
Sorry for english mistakes!
the code is in event
procedure TfMain.TCPServerExecute(AThread: TIdPeerThread);
Bruno
"Felipe Molina" <cre...@terra.es> wrote in message news:3b174954_2@dnews...
> Server side;
>
> with AThread.Connection do begin
> sCommand := ReadLn;
> if SameText(cOPY(sCommand, 1, 6), 'UPLOAD') then begin
> //stream:=Tmemorystream.create;
stream := tfilestream.create(filename,fmCreate);
> ReadStream(stream);
> //stream.SaveToFile(filename);
> stream.free; end;
>
> Client side:
>
> stream:=TmemoryStream.create;
> IdTCPClient1.host:=Ehostname.text;
> IdTCPClient1.connect;
> memo1.clear;
> Try
> Memo1.lines.Add(IdTCPClient1.ReadLn);
> IdTCPClient1.writeLn('UPLOAD'+FilenameEdit1.TEXT);
> while IdTCPClient1.connected do
> begin
> IdTCPClient1.OpenWriteBuffer;
> //IdTCPClient1.WriteStream(stream);
IdTCPClient1.WriteStream(stream,true,true);
> IdTCPClient1.CloseWriteBuffer;
> stream.free;
> IdTCPClient1.disconect;
>
Two changes -
1. you don't need to use a TMemoryStream on the server - that will eat up a
bunch of memory every time you transfer a file.
2. By default, the ReadStream function assumes that there is a byte count
included in the stream. However, the default for WriteStream doesn't include
this byte count. You have to use the (...,true,true) parameters to get this
to happen.
Comments
- I don't usually use the OpenWriteBuffer/CloseWriteBuffer methods. Without
them, it is my understanding that the data is sent as the various WriteXXX
methods are called. In this case, since you are sending a stream, it can go
all at once anyway. Especially since as written, there is a memory
allocation equal to the size of the stream you are sending. Depending on the
client machine, this may or may not be significant. I try to make as few
demands on client-side RAM as possible in this kind of situation.
- I assume you are filling the TMemoryStream on the client with some data
before you send it. If you are loading it from a file, it is more efficient
to use a TFileStream as in change #1, above.
HTH...
brian
procedure FaxSucheDateiName;
var
IstDa : boolean;
IstNummer : integer;
begin
IstDa := true; IstNummer := 1;
while IstDa do begin
FData.APFDateiName := Faxverzeichnis
+ '\' + FormatDateTime('yymmdd"_"hhnnss', now)
+ IntToStr(IstNummer) + '.APF';
IstDa := FileExists(FData.APFDateiName);
inc(IstNummer);
end;
FData.APXDateiName := ChangeFileExt(FData.APFDateiName, '.APX');
end;
{ ------------------- Einzelbefehle ------------------- }
procedure FaxStop;
begin
FData.Beenden := true;
FData.BefehlsNummer := 0;
end;
procedure FaxFehler;
begin
AThread.Connection.WriteLn('STOP');
FData.Beenden := true;
FData.BefehlsNummer := 0;
end;
procedure FaxClientStart;
begin
AThread.Connection.WriteLn('TRUE');
if FData.CliPhase = 0 then FData.CliPhase := 1
else FaxFehler;
FData.BefehlsNummer := 0;
end;
procedure FaxClientReply;
begin
AThread.Connection.WriteLn('FALSE');
if FData.CliPhase = 1 then FData.CliPhase := 2
else FaxFehler;
FData.BefehlsNummer := 0;
end;
procedure FaxFileNameXX;
begin
FData.FaxInfo.Add('FILENAM ' + FData.EmpfangString);
if FData.CliPhase = 2 then FData.CliPhase := 3
else FaxFehler;
FData.DerPuffer := TMemoryStream.Create;
try
AThread.Connection.ReadStream(FData.DerPuffer);
FaxSucheDateiName;
FData.DerPuffer.SaveToFile(FData.APFDateiName);
FData.FaxInfo.SaveToFile(FData.APXDateiName);
finally
FData.DerPuffer.Free;
FData.DerPuffer := NIL;
AThread.Connection.WriteLn('OK');
end;
FData.Beenden := true;
FData.BefehlsNummer := 0;
end;
procedure FaxAbsender;
begin
FData.FaxInfo.Add('ABSENDR ' + FData.EmpfangString);
FData.BefehlsNummer := 0;
end;
procedure FaxFNummer;
begin
FData.FaxInfo.Add('FNUMMER ' + FData.EmpfangString);
FData.BefehlsNummer := 0;
end;
procedure FaxKennung;
begin
FData.FaxInfo.Add('KENNUNG ' + FData.EmpfangString);
FData.BefehlsNummer := 0;
end;
procedure FaxKopfName;
begin
FData.FaxInfo.Add('KOPFNAM ' + FData.EmpfangString);
FData.BefehlsNummer := 0;
end;
procedure FaxAnzahl1;
begin
FData.FaxInfo.Add('ANZAHL1 ' + FData.EmpfangString);
FData.BefehlsNummer := 0;
end;
procedure FaxRHeader;
begin
FData.FaxInfo.Add('HEADER ' + FData.EmpfangString);
FData.BefehlsNummer := 0;
end;
procedure FaxPriori;
begin
FData.FaxInfo.Add('PRIORI ' + FData.EmpfangString);
FData.BefehlsNummer := 0;
end;
procedure FaxRunServer;
var
Gefunden : integer;
SuchRec : TSearchRec;
Fehler : Boolean;
begin
Fehler := false;
Gefunden := FindFirst(Faxverzeichnis + '*.APX', faAnyFile, SuchRec);
while (Gefunden = 0) and (SuchRec.Size > 0) do begin
FData.APXDateiName := Faxverzeichnis + SuchRec.Name;
FData.APFDateiName := ChangeFileExt(FData.APXDateiName, '.APF');
AThread.Connection.WriteLn('FILE');
FData.DerPuffer := TMemoryStream.Create;
try
FData.DerPuffer.LoadFromFile(FData.APXDateiName);
FData.DerPuffer.Seek(0, soFromBeginning);
try
AThread.Connection.WriteStream(FData.DerPuffer, true, true);
except
Fehler := true;
end;
FData.DerPuffer.Clear;
FData.DerPuffer.LoadFromFile(FData.APFDateiName);
FData.DerPuffer.Seek(0, soFromBeginning);
try
AThread.Connection.WriteStream(FData.DerPuffer, true, true);
except
Fehler := true;
end;
if not Fehler then begin
DeleteFile(FData.APXDateiName);
DeleteFile(FData.APFDateiName);
end;
finally
FData.DerPuffer.Free;
FData.DerPuffer := NIL;
end;
Gefunden := FindNext(SuchRec);
end;
if not Fehler then AThread.Connection.WriteLn('OK')
else AThread.Connection.WriteLn('ERR');
FData.Beenden := true;
FData.BefehlsNummer := 0;
end;
procedure ProcessFax;
begin
if FData.BefehlsNummer = 0 then begin
FData.Befehl := Fetch(FData.EmpfangString, ' ');
if FData.Befehl = 'CLIENTF' then FData.BefehlsNummer := 1 else
if FData.Befehl = 'AAAAAAA' then FData.BefehlsNummer := 2 else
if FData.Befehl = 'FILENAM' then FData.BefehlsNummer := 3 else
if FData.Befehl = 'ABSENDR' then FData.BefehlsNummer := 4 else
if FData.Befehl = 'FNUMMER' then FData.BefehlsNummer := 5 else
if FData.Befehl = 'KENNUNG' then FData.BefehlsNummer := 6 else
if FData.Befehl = 'KOPFNAM' then FData.BefehlsNummer := 7 else
if FData.Befehl = 'ANZAHL1' then FData.BefehlsNummer := 8 else
if FData.Befehl = 'HEADER:' then FData.BefehlsNummer := 9 else
if FData.Befehl = 'PRIORI:' then FData.BefehlsNummer := 10 else
if FData.Befehl = 'SERVER' then FData.BefehlsNummer := 101 else
//if FData.Befehl = 'CLIENT' then FData.BefehlsNummer := 1 else
if FData.Befehl = 'STOP' then FData.BefehlsNummer := 998 else
FData.BefehlsNummer := 999;
end; { if FData.BefehlsNummer = 0 }
(* LoggSektion.Enter; { ------ Block -------- } //only for debug
Fm_Haupt.DerLogText := FData.Befehl + IntToStr(FData.BefehlsNummer);
//only for debug
AThread.Synchronize(Fm_Haupt.SchreibeLog); //only for debug
LoggSektion.Leave; { ------ Block -------- } //only for debug *)
case FData.BefehlsNummer of
1 : FaxClientStart;
2 : FaxClientReply;
3 : FaxFileNameXX;
4 : FaxAbsender;
5 : FaxFNummer;
6 : FaxKennung;
7 : FaxKopfName;
8 : FaxAnzahl1;
9 : FaxRHeader;
10 : FaxPriori;
101 : FaxRunServer;
998 : FaxStop;
999 : FaxFehler;
else FaxFehler;
end; { case FData.BefehlsNummer of }
end; { procedure ProcessFax }
begin { ------------------- Execute ------------------- }
FData := Pointer(AThread.Data);
try
FData.BefehlsNummer := 0;
FData.CliPhase := 0;
FData.SerPhase := 0;
FData.TimeOutCount := 0;
FData.Beenden := false;
AThread.Connection.WriteLn('START');
while AThread.Connection.Connected and (not FData.Beenden)
and (FData.TimeOutCount <= 60) do begin
FData.EmpfangString := AThread.Connection.ReadLn('', 1000);
if (not AThread.Connection.ReadLnTimedOut) then begin
FData.TimeOutCount := 0;
(* LoggSektion.Enter; { ------ Block -------- } //only for debug
Fm_Haupt.DerLogText := FData.EmpfangString; //only for debug
AThread.Synchronize(Fm_Haupt.SchreibeLog); //only for debug
LoggSektion.Leave; { ------ Block -------- } //only for debug *)
ProcessFax;
end else FData.TimeOutCount := FData.TimeOutCount + 1;
end;
finally
if AThread.Connection.Connected
then AThread.Connection.Disconnect;
end;
end;
procedure TFm_Server.EG_FaxServerConnect(AThread: TIdPeerThread);
var
FData : TFaxData;
begin
FData := TFaxData.Create;
AThread.Data := FData;
FData.FaxInfo := TStringList.Create;
end;
procedure TFm_Server.EG_FaxServerDisconnect(AThread: TIdPeerThread);
var
FData : TFaxData;
begin
FData := Pointer(AThread.Data);
if FData.FaxInfo <> NIL then begin
FData.FaxInfo.Free;
FData.FaxInfo := NIL;
end;
if FData.DerPuffer <> NIL then begin
FData.DerPuffer.Free;
FData.DerPuffer := NIL;
end;
FData.Free;
AThread.Data := nil;
end;
---------------------
--
Ernst Gerlach
ernst....@epost.de
http://www.gerlach-mtl.de
--- use plain text only in email ---
Mystream.readFromWhatever;
// at this point the stream's position is the same as it's size
// and if you try to write it somewhere, either to a socket or to a file,
nothing will happen,
// since writing assumes you are starting at the current position and going
to the end.
// so you need this:
Mystream.position := 0;
// now the stream is ready for the next thing
Client.sendstream or athread.connection.readstream
HTH
Brandon
"Felipe Molina" <cre...@terra.es> wrote in message news:3b174954_2@dnews...