Newsgroup: it.comp.lang.delphi
Titolo: Indy e trasferimento file

Lo so direte che non mi va di studiare... fidatevi ci provo ma la 
documentazione fa schifo.
Dunque devo trasferire un file da un idTCPClient a un idTPCServer e 
viceversa (uso i Filestream per una velocità maggiore).
Da client:
FStream := TFileStream.Create(Nome_Completo, fmOpenRead);
TCPClient.IOHandler.Write(FStream, 0, False);
FreeAndNil(FStream);
Da server:
FStream := TFileStream.Create(NomeFile, fmCreate);
AContext.Connection.IOHandler.ReadStream(FStream, Dimensione, True);
FreeAndNil(FStream);
i problemi sono due:
1) la chiamata Write del client viene subito passata (dura pochissimo) 
anche se il file non è stato completamente trasferito, quindi non so se 
ho finito o meno (mi serve di saperlo in quanto è possibile che un'altro 
thread richieda le informazioni sul file appena trasferito).
2) finchè non chiudo il server la chiamata readStream non esce.
Qualcuno ha qualche idea? Ho visto gli esempi con indy 9 e mi pare che 
ho fatto tutto correttamente (esempi per indy 10 non esistono - almeno 
non sono riuscito a trovarli)
Grazie a tutti,
David

 viceversa (uso i Filestream per una velocità maggiore).
xche non ftp?
A.

 thread richieda le informazioni sul file appena trasferito).
non so se ho capito:
se il server non andasse in palle potresti mettere un readln() subito dopo 
il write del client, ricevuto come conferma di stream ricevuto dal 
server...ma se il server si blocca sul readstream() forse c'è qualcosa che 
non va...
V. 

 thread richieda le informazioni sul file appena trasferito).
La Write è sincrona (non conosco l'IOHandler di Indy 10, nei precedenti
c'è WriteStream) quindi, teoricamente, quando la Write termina, il
contenuto del file è stato trasferito.  
Con Indy 9 io scrivo sempre e la dimensione dei dati e i dati stessi, come
stream.  Lato server leggo la dimensione dei dati e successivamente lo
stream.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

E qui' casca l'asino. Pure io lo credevo invece sembra che la write sia 
asincrona nella versione 10. Non so' che pesci pigliare e, il bello è 
che non posso neanche tornare alla versione 9 in quanto sembra che non 
sia pienamente supportata da Delphi 2006.

> xche non ftp?
L'applicativo è un simil gestionale che lavora in rete. L'ftp mi serve a 
poco.

 stream.
Si, anch'io faccio così ed il trasferimento va sempre a buon fine
[cit]
TCPClient.IOHandler.Write(FStream, 0, False);
...
AContext.Connection.IOHandler.ReadStream(FStream, Dimensione, True);
[/cit]
ma il parametro Dimensione da dove se lo pesca? legge autonomamente la 
grandezza dello stream?
V.

Ho provato a mettere un Readln dopo l'invio ma nulla. Il server si 
pianta e, il bello, è che il file non viene chiuso finquando non termino 
il server vero e proprio.

Si la legge automaticamente... meglio puoi passarla o meno (ho provato 
entrambe le soluzioni ma con lo stesso risultato)

 asincrona nella versione 10. 
Poco male.  C'è sempre un modo per rendere sincroni i comportamenti
asincroni.
Se la Write() lavora in modo asincrono (anche se mi sembra strano), ci
sarà sicuramente un evento "threaded" che ti informa quando ha terminato. 


C'e' ed è OnWorkEnd solamente che non funziona. Ovvero ritorna 
immediatamente la fine dell'operazione.

 immediatamente la fine dell'operazione.
si però il problema del piantamento del server durante il readstream 
permarrebbe comunque...se poi il server non chiude il file se non quando lo 
si termina forse significa che per lui l'operazione sullo stream non è 
conclusa...
anche se può sembrare banale...ho dato un'occhiata ai metodi di Indy10 e 
write e readstream lavorano con parametri che devono essere in sincronia 
l'uno con l'altro...li hai verificati al meglio immagino?
Dimensione lo hai dichiarato come Int64?

 immediatamente la fine dell'operazione.
si però il problema del piantamento del server durante il readstream




No, OnWorkEnd (che c'era anche prima, per identificare l'inizio e la
fine della singola trasmissione) non è ciò a cui mi riferivo.

permarrebbe comunque...
Il server non si "pianta", è solo in attesa di altri dati.
Evidentemente la dimensione dei dati spediti lato client non è quella
che il server si aspetta.

 che il server si aspetta.
mi sono espresso male ma è quello a cui mi riferivo...il write() e
readstream() di Indy10 è diverso dal 9...da quello che ho visto non è
necessario inviare con un writeln() separato la dimensione dello stream ma
puoi assegnarla direttamente all'interno della stessa writeln() - come
invece lasciare il valore in bianco -
il readstream() prevede la lettura di questo valore direttamente dal write()
oppure lo evince da sè...per questo parlavo di parametri in sincronia...se
il client invia la dimensione il server deve trovare settata una boolean che
gli indica che c'è una dimensione predefinita e via discorrendo...
ma l'ho buttata lì, evidentemente il controllo è già stato fatto...
ciao
V.

Un esempio che mi funzionava, Giorgio
function TClientTh.InviaComando: Boolean;
begin
Result:=False;
BuffCli:=TMemoryStream.Create;
WrappStreamCli:=TIdStreamVCL.Create(BuffCli, True);
Try
  Parametri.SaveToStream(WrappStreamCli.VCLStream);
  // Invia il Comando e i Parametri (TStringList)
  With Client.IOHandler do
    begin
    Writeln(Comando);
    Write(WrappStreamCli.Size);
    WriteBufferOpen;
    Write(WrappStreamCli);
    WriteBufferClose;
    end;
  Result:=True;
finally
  FreeAndNil(WrappStreamCli);
  end;
end;