Hola Maxinito, Te comento, esto es muy sencillo, Creo que en D2009 ya viene con los componentes Indy.
La teoria es la siguiente. (por lo menos asi lo Hago yo).
Primero Mando un mensaje desde el origen, con El nombre del archivo y el Tamaño.
en el Receptor tomo el nombre del archivo y el Tamaño.
Luego envio un Stream desde el Origen.
En el receptor, Recibo el Stream hasta que el tamaño sea el mismo que en el Cliente.
El codigo esta hecho para componentes Indy 10
saludos
Código Delphi
[-]
procedure Cliente.SendFile(Sender: TObject);
var
St:TFileStream;
begin
try
SendFile.InitialDir:=ExtractFilePath(ParamStr(0));
SendFile.Execute;
If SendFile.FileName<>'' then begin
st:=TFileStream.Create(SendFile.FileName,fmopenread);
Client.WriteLn('CMD#SNDFile#'+ExtractFileName(SendFile.FileName)+'#'+IntToStr(st.Size));
if Client.ReadLn='RCVFile#Ready' then begin
Try
client.WriteStream(st,true,true,st.Size);
except
end;
end else
ShowMessage('Cant Send the File');
end;
finally
St.Free;
end;
end;
Código Delphi
[-]
procedure Server.ServerExecute(AThread: TIdPeerThread);
begin
if RcvFile then begin
Try
if st.Sizethen begin
AThread.Connection.ReadStream(st);
end;
if st.Size=size then begin
RcvFile:=false;
size:=0;
st.free;
AThread.Connection.WriteLn('RESP#File received OK');
FileName:='';
exit;
end;
except
AThread.Connection.WriteLn('RESP#File Not Received');
RcvFile:=false;
size:=0;
st.free;
if FileExists(FileName) then
DeleteFile(FileName);
FileName:='';
exit;
end;
end;
If pos('SNDFile',s)<>0 then begin
Delete(s,1,pos('#',s));
Filename:=copy(s,1,pos('#',s)-1);
delete(s,1,pos('#',s));
size:=StrToInt(s);
st:=TFileStream.Create(FileName,fmCreate);
AThread.Connection.WriteLn('RCVFile#Ready');
RcvFile:=true;
end
Este Codigo envia esos mensajes y utiliza laClausula RcvFile ya que utilizo el mismo Socket para todo.
Otra opcion seria abrir una nueva comunicacion por un puerto distinto y se podria continuar recibiendo mensajes mientras se recibe el archivo, en el caso que se trate de un Chat.
saludos y espero que sea util.