Newsgroup: it.comp.lang.delphi
Titolo: Carlo Bertuccini

Tnx!
Funziona!
Ho solo un problema.
Quello che il tuo codice fa lo devo mettere in un loop
Ora, mi sembra di aver capito che il client riceve l'immagine lla chiusura
del socket dal parte del server.
Se è cosi' dovrei mettere tutto il blocco ricezione in un loop.
Ma non mi sembra che vada.
Posso aprofittare ancora una volta della tua disponibilita?
Grazie e scusa il disturbo
AS
"Se è Microsoft non funziona"

 Posso aprofittare ancora una volta della tua disponibilita?
Vabbè ... si! :-)
Bye!
--
- Carlo -
ps : non aprite thread a mio nome (uso il plurale perchè non è la prima
volta che succede ...)

    Hai un po' di confusione con le connessioni bloccanti e non bloccanti
 o se preferisci sincrone o asincrone ).
    I socket di Delphi sono settati per default in modo asincrono... Vale a
dire che il server resta in attesa di un messaggio e fa qualcosa quando
questo gli arriva... E' il server stesso che determina quando  tutto il
messaggio gli è arrivato, controllando che il buffer dei dati sia vuoto, e
fa le relative operazioni.
    Quando si deve spedire un grosso quantitativo di dati ( maggiore di 30
kb ) la connessione asincrona non va più bene perché il file viene spedito
"a fiotti" (immagina l'acqua che scorre in una conduttura rigida ), cioé il
buffer del lato server viene riempito, svuotato, riempito ancora, svuotato
ancora. Se sei in modalità asincrona il server riceve solamente il primo
quantitativo che è arrivato nel buffer e ignora gli altri e tu ti trovi con
una serie di dati incompleta.
    La soluzione è passare alle connessioni bloccanti dove si istruisce il
server di aspettare un qunatitativo di dati pari a x byte. In questo modo il
server continua ad aspettare i dati finché non si arriva al quantitativo
prefissato o finché non scade il time - out di connessione impostato. Ecco
perché non è necessario mettere in un loop il codice che ti ha postato
Carlo. Il problema reale è che il server non è più disponibile ad ascoltare
altri dati finché non si verifica uno dei due casi che ti ho citato e
soprattutto non è più n grado di determinare autonomamente quando la
connessione è terminata (e quindi non reagisce più agli altri comandi
asincroni).
    In definitiva:
    - se devi gestire comandi è necessaria la connessione asincrona
    - se devi trasferire file è necessaria quella sincrona (devi impostare
sia server che client a ctBlocking) ricordandoti che in questo stato il
server non è più in grado di elaborare comandi asincroni.
    Le soluzioni che hai per fare il trasferimetno dei dati sono queste:
    - mandi un comando al server che gli dice di mettersi in modalità
sincrona e una volta terminato il trasferimento di tornare in modalita
asincrona
    - crei due server in ascolto su porte diverse uno sincrono e uno
asincrono
    Saluti!
_________________________________
Gian Luca Dalla Torre
E - Mail: 
gianluca....@casteo.net
_________________________________

La mia situazione č questa.
Il server invia una immagine ad un client remoto.
L'immagine č un frame catturato da una sorgente video esterna.
In pratica, ho un timer che ogni x secondi cattura un frame di tipo bmp, lo
converte in jpeg e lo deve inviare ad un client eventualmente connesso al
server.
Il codice postato da Carlo create uno stream specifico per i socket per
gestire questa situazione:
Lato ricezione :
var
  Stream: TWinSocketStream;
  Buffer: Array [0..9999] of Byte;
  MemoryStream: TMemoryStream;
  Received: Integer;
  JPeg : TJpegImage;
begin
  Form1.ClientSocket2.Active:=True;
  JPeg := TJpegImage.Create;
  Stream:= TWinSocketStream.Create ( Form1.ClientSocket2.Socket, 360000 );
  MemoryStream:= TMemoryStream.Create;
  try
    if Stream.WaitForData ( 360000 ) then
    begin
      while True do
      begin
        Received:= Stream.Read ( Buffer, SizeOf ( Buffer ) );
        MemoryStream.Write ( Buffer, Received );
        if Received <= 0 then
          break;
       end;
       MemoryStream.Position:= 0;
       JPeg.LoadFromStream ( MemoryStream );
       Image1.Picture.Assign(Jpeg);
    end;
  finally
    Stream.Free;
    JPeg.Free;
    MemoryStream.Free;
    Form1.ClientSocket2.Active:= False;
  end;
Lato spedizione :
Jpg := TJpegImage.Create;
Stream:= TWinSocketStream.Create
                        ( ServerSocket2.Socket.Connections[0], 360000 );
try
  Jpg.LoadFromFile( 'file' );
  Jpg.SaveToStream ( Stream );
finally
  Stream.Free;
  ServerSocket2.Socket.Connections[0].Close;
end;
Jpg.Free;
Mi domando:
Il blocco in trasmissione viene eseguito sempre?
O meglio, il seguente codice:
Stream:= TWinSocketStream.Create
                        ( ServerSocket2.Socket.Connections[0], 360000 );
attiva un qualcosa che gia' di per se gestisce un loop?
Ed in ricezione vale lo stesso con il seguente codice? O meglio, lui sta
sempre in attesa di ricevere qualcosa dal server?
  Stream:= TWinSocketStream.Create ( Form1.ClientSocket2.Socket, 360000 );
Scusate se sono poco chiaro, ma con questa roba ho iniziato a lavorare circa
24 ore lavorative fa....
Saluti
AS
"Se č Microsoft non funziona"


    Questta seconda riga di codice fa la stessa cosa dell'altra dal lato
client, in pratica queste due righe che vengono eseguite prima della
scadenza del time - out ti attivano una connessione sincrona...
    Quello che a te manca è il fatto di far capire sia al programma server
che al programma client quando devono sincronizzarsi ed eseguire il blocco
delle istruzioni che ti ha passato Carlo.
    L'idea più semplice che mi viene in mente è che tu aggiunga un altro
componente ServerSocket e ClientSocket sulle due applicazioni, li usi in
modalità asincrona e fai in modo che quando si genera l'evento del timer,
venga spedito al client un messaggio del tipo "ehi è ora di sincronizzarsi",
quell'altro ricevendo il messaggio attiva il blocco di ricezione... Nel
frattempo anche il server avvia il suo blocco e l'immagine è scambiata...
Ogni volta che avviene l'acquisizione dell'immagine devi fare questo tipo di
sincroniozzazione... Come vedi è ben diversa da un loop ;-)
    Ciao!
