Newsgroup: it.comp.lang.delphi
Titolo: TServerSocket e TClientSocket

Salve. Ho un problema e spero che mi aiutate nel risolverlo.
Ho implementato una procedura per inviare e ricevere file tramite Socket.
Premetto che ho settato "Servertype=stNonBlocking"
Queste sono le procedure :
----------------------------------------------------------------------------
--------------------
procedure TMainForm.ServerClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  nomedelcomando:=Socket.ReceiveText;
  if pos('XXGETMID',nomedelcomando)=1 then
  begin
    Nomedelfile:=Copy(nomedelcomando,9,192);
    try
// invio il comando
      Socket.SendText('XXGETMID'+Nomedelfile);
// invio il file
      Socket.SendStream(TFileStream.Create(Nomedelfile,fmOpenRead));
    except
    end;
  end
............................................................................
..............................................
procedure TMainForm.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var Mesg,Nomefile:String;
    nreceived:Integer;
    Buffer:array[0..1024] of char;
    Handle:Integer;
    i:Integer;
begin
   BUFFER:='';
//ricevo il comando
   Socket.ReceiveBuf(buffer,200);
   mesg:=copy(buffer,1,8);
   if mesg ='XXGETMID' then
   begin
      nomefile:=Trim(Copy(buffer,9,length(buffer)-8));
      Nomefile:=ExtractFileName(Nomefile);
      Handle:=FileCreate(nomefile);
      while True do
      begin
        FillChar(Buffer, SizeOf(Buffer), 0);
        nreceived:=Socket.ReceiveBuf(buffer,sizeof(buffer));
        if nreceived<=0 then
           Break
        else
          FileWrite(Handle,buffer,nreceived);
        Sleep (200);
      end;
      FileClose(Handle);
   end
............................................................................
.............
----------------------------------------------------------------------------
---------------------------
il problema è che non posso inviare file con dimensione maggiori di 28672
byte
Se invio un file di 12000 byte è OK
Se invio un file di 50000 byte mi ritrovo con un file di dimensioni 28672.
Perchè succede e come posso fare per inviare file di dimensioni illimitati ?
Grazie tante.

 dimensioni illimitati ? Grazie tante.
Secondo me la cosa migliore è che ti scrivi un piccolo protocollo.
Niente di eccezionale, sia chiaro, giusto un record all'inizio dello stream
che indica quanti bytes
dati ci sono nello stream stesso, più magari un minimo di controlli sulla
integrità dei dati( tipo un
CRC  o roba simile ).
Con questo sistema puoi mandare files in "spezzoni" che non si perdono.
Ciao
Andrea

Anche se potrei implementare una cosa del genere,
però vorrei sapere perchè succede questo.

   end
Prima di tutto, non ritengo corretto trappere l'eccezione in questo modo in
quanto se una qualsiasi cosa va storta, tu non lo saprai mai, tranne che se
stai eseguendo la applicazione da ide con l'opzione Stop on delphi Exception
abilitata.
Questo non vale solo x questo caso, ma come regola generale.
Trattandosi di una comunicazione asincrona, sarebbe inoltre il caso di
vedere se e come gestisci gli eventi di errore dei 2 componenti.
Se metti una ErrorCode=0 senza nessun tipo di notifica non saprai mai se hai
avuto problemi sul collegamento.
Poi, sostiturei:
Socket.SendText('XXGETMID'+Nomedelfile);
con:
Socket.SendStream(TStringStream.Create('XXGETMID'+Nomedelfile));
Inoltre, forse il protocollo ha un suo buffer con una certa dimensione,
superata la quale inizia a perdere bytes.
E' sintomatico il fatto che non vada oltre i 28.000 circa....
magari lo sleep non servirebbe tanto in ricezione quanto in trasmissione, in
modo da dare tempo a chi riceve di leggere cio che è stato inviato svuotando
questo (ipotetico??) buffer e lasciando quindi spazio x un altro pacchetto
di dati
Prova a leggere che so, 20000 bytes alla volta e a inviarli, aumentando
magari le dimensioni del buffer che usi in ricezione e mettendo una pausa
tra un invio e l'altro.
Anzi, la dimensione del pacchetto da inviare potrebbe essere letta da un
file ini in modo da poterla adattare alle varie possibilità senza dover
ricompilare tutto..
Sarebbe poi giusto avere una response che ti ritorna il numero di bytes
effettivamente ricevuti dall'altra parte in modo da sapere se l'ultimo
pacchetto è stato effettivamente ricevuto conmpleto.
Ancora, io non scarteri la possibilità di avere un socket sincrono.
La implementazione è leggermente + complessa, ma ti eviti tutta una serie di
problemi legati alla comunicazione asincrona tra i 2 processi.
Ch riceve si mette li e aspetta tentando di leggere n bytes dal suo
interlocutore.
Se vai in timeout tu lo sai e ti puoi regolare di conseguenza.
Infine, forse gli Indy danno un minimo di supporto in +.
In d7 i TClientSocket e TServerSocket non vengono installati di default e
mamma borland invita a usare gli indy.
Io lo avrei gia fatto, ma al momento ho 2 progetti basati su TClient e
TserverSocket sviluppati in d5e e se volessi cambiare i componenti dovrei
riscrivere parte del codice senza contare che le tarantelle di questi,a
differenza di quelle degli indy, le conosco....
Considerato che uno di questi progetti dovrebbe essere pronto x IERI... :)))
Bye
A.