Aquí tienen cómo se envía un stream o un archivo con Indy10 dentro de una red de ordenadores.
Incluye el procedimiento principal en el Cliente y en el Server, junto con algunas funciones genéricas:
function ReceiveBuffer(AClient: TIdTCPClient; var ABuffer: TBytes): Boolean;
function SendBuffer(AClient: TIdTCPClient; ABuffer: TBytes): Boolean;
function SendBuffer(AContext: TIdContext; ABuffer: TBytes): Boolean;
function ReceiveBuffer(AContext: TIdContext; var ABuffer: TBytes): Boolean;
function ReceiveStream(AContext: TIdContext; var AStream: TStream): Boolean;
function ReceiveStream(AClient: TIdTCPClient; var AStream: TStream): Boolean;
function SendStream(AContext: TIdContext; AStream: TStream): Boolean;
function SendStream(AClient: TIdTCPClient; AStream: TStream): Boolean;
function ClientSendFile(AClient: TIdTCPClient; Filename: String): Boolean;
function ServerReceiveFile(AContext: TIdContext; ServerFilename: String;
- ENVIAR UN STREAM
Desde el Server:
var
afS_s,afS_r:tMemoryStream;
PROCEDURE TStreamServerForm.IdTCPServer1Execute(AContext: TIdContext);
BEGIN
afS_s := TmemoryStream.Create;
afS_r := TmemoryStream.Create;
TRY
Memo1.Lines.Add('Server starting .... ');
Image1.Picture.Bitmap.SaveToStream(aFS_s);
aFS_s.Seek(0, soFromBeginning);
AContext.Connection.IOHandler.ReadTimeout := 9000;
IF (ReceiveStream(AContext, TStream(aFS_r)) = False) THEN
BEGIN
TIdNotify.NotifyMethod(ShowCannotGetBufferErrorMessage);
Exit;
END;
Memo1.Lines.Add('size received stream ' + IntToStr(aFS_r.Size));
Image1.Picture.Bitmap.LoadFromStream(aFS_R);
aFS_r.Position := 0;
Image1.Picture.Bitmap.LoadFromStream(aFS_r);
TIdNotify.NotifyMethod(StreamReceived);
IF (SendStream(AContext, TStream(aFS_s)) = False) THEN
BEGIN
TIdNotify.NotifyMethod(ShowCannotSendBufferErrorMessage);
Exit;
END;
Memo1.Lines.Add('Stream sent');
Memo1.Lines.Add('Server done .... ');
FINALLY
aFS_s.Free;
aFS_r.Free;
END;
END;
Desde el cliente:
procedure torm1.Button_SendStreamClick(Sender: TObject);
begin
aFs_s := TmemoryStream.Create;
aFs_r := TmemoryStream.Create;
Image1.Picture.Bitmap.SaveToStream(aFs_s);
aFs_s.Seek(0,soFromBeginning);
Memo1.Lines.Add('Try send stream to server.....');
if (SendStream(IdTCPClient1, TStream(aFs_s)) = False) then
begin
Memo1.Lines.Add('Cannot send STREAM to server, Unknown error occured');
Exit;
end;
Memo1.Lines.Add('Stream successfully sent');
if (ReceiveStream(IdTCPClient1, TStream(aFs_r)) = False) then
begin
Memo1.Lines.Add('Cannot get STREAM from server, Unknown error occured');
Exit;
end;
//Hay que tener en cuenta que tMemo no es threadsafe y puede dar problemas
// quizás seria conveniente quitar la línea de abajo
Memo1.Lines.Add('Stream received: ' + IntToStr(aFs_r.Size));
//SetClientState(False);
aFs_r.Position := 0;
Image1.Picture.Bitmap.LoadFromStream(aFs_r);
aFS_s.Free;
aFS_r.Free;
end;
//al conectar
procedure Tform1.CheckBox1Click(Sender: TObject);
begin
if (CheckBox1.Checked = True) then
begin
IdTCPClient1.Host := '127.0.0.1';
IdTCPClient1.Port := 6000;
IdTCPClient1.Connect;
end
else
IdTCPClient1.Disconnect;
end;
- ENVIAR O RECIBIR UN RECORD/BUFFER/FILE.
En el Server
procedure Tform1.IdTCPServer1Execute(AContext: TIdContext);
var
LSize: LongInt;
file1 : String;
dummyStr : string;
begin
Memo1.Lines.Add('Server starting .... ' );
AContext.Connection.IOHandler.ReadTimeout := 9000;
dummyStr := AContext.Connection.IOHandler.ReadLn;
file1:= FileNameEdit.Text;
if ( ServerSendFile(AContext, file1) = False ) then
begin
TIdNotify.NotifyMethod(ShowCannotGetFileErrorMessage);
Exit;
end
else
begin
Memo1.Lines.Add('Server done, client file -> ' + file1);
end;
TIdNotify.NotifyMethod(FileReceived);
end;
procedure Tform1.FileReceived;
begin
Memo1.Lines.Add('File received' );
end;
En el cliente
procedure TForm1.Button_SendStreamClick(Sender: TObject);
var
LSize: LongInt;
begin
LSize := 0;
Memo1.Lines.Add('Try send stream to server.....');
IdTCPClient1.Host := '127.0.0.1';
IdTCPClient1.Port := 6000;
IdTCPClient1.IOHandler.WriteLn('GET FILE NOW');
if (ClientReceiveFile(IdTCPClient1, FileNameEdit.Text) = False) then
begin
Memo1.Lines.Add('Cannot get record/buffer to server->' +
FileNameEdit.Text);
Exit;
end
else
begin
Memo1.Lines.Add('get record/buffer to server, save as ....' + FileNameEdit.Text);
end;
SetClientState(false);
end;
FUNCIONES GENÉRICAS PARA ENVIAR O RECIBIR STREAMS/FILES
function ReceiveBuffer(AClient: TIdTCPClient; var ABuffer: TBytes)
: Boolean;
var
LSize: LongInt;
begin
Result := True;
try
LSize := AClient.IOHandler.ReadLongInt();
AClient.IOHandler.ReadBytes(ABuffer, LSize, False);
except
Result := False;
end;
end;
function SendBuffer(AClient: TIdTCPClient; ABuffer: TBytes): Boolean;
begin
try
Result := True;
try
AClient.IOHandler.Write(LongInt(Length(ABuffer)));
AClient.IOHandler.WriteBufferOpen;
AClient.IOHandler.Write(ABuffer, Length(ABuffer));
AClient.IOHandler.WriteBufferFlush;
finally
AClient.IOHandler.WriteBufferClose;
end;
except
Result := False;
end;
end;
function SendBuffer(AContext: TIdContext; ABuffer: TBytes): Boolean;
begin
try
Result := True;
try
AContext.Connection.IOHandler.Write(LongInt(Length(ABuffer)));
AContext.Connection.IOHandler.WriteBufferOpen;
AContext.Connection.IOHandler.Write(ABuffer, Length(ABuffer));
AContext.Connection.IOHandler.WriteBufferFlush;
finally
AContext.Connection.IOHandler.WriteBufferClose;
end;
except
Result := False;
end;
end;
function ReceiveBuffer(AContext: TIdContext; var ABuffer: TBytes)
: Boolean;
var
LSize: LongInt;
begin
Result := True;
try
LSize := AContext.Connection.IOHandler.ReadLongInt();
AContext.Connection.IOHandler.ReadBytes(ABuffer, LSize, False);
except
Result := False;
end;
end;
///
/// --------------------- HELP FUNCTION FOR STREAM EXCHANGE --------------
///
function ReceiveStream(AContext: TIdContext; var AStream: TStream)
: Boolean;
var
LSize: LongInt;
begin
Result := True;
try
LSize := AContext.Connection.IOHandler.ReadLongInt();
AContext.Connection.IOHandler.ReadStream(AStream, LSize, False);
except
Result := False;
end;
end;
function ReceiveStream(AClient: TIdTCPClient; var AStream: TStream)
: Boolean;
var
LSize: LongInt;
begin
Result := True;
try
LSize := AClient.IOHandler.ReadLongInt();
AClient.IOHandler.ReadStream(AStream, LSize, False);
except
Result := False;
end;
end;
function SendStream(AContext: TIdContext; AStream: TStream): Boolean;
var
StreamSize: LongInt;
begin
try
Result := True;
try
StreamSize := (AStream.Size);
// AStream.Seek(0, soFromBeginning);
AContext.Connection.IOHandler.Write(LongInt(StreamSize));
AContext.Connection.IOHandler.WriteBufferOpen;
AContext.Connection.IOHandler.Write(AStream, 0, False);
AContext.Connection.IOHandler.WriteBufferFlush;
finally
AContext.Connection.IOHandler.WriteBufferClose;
end;
except
Result := False;
end;
end;
function SendStream(AClient: TIdTCPClient; AStream: TStream): Boolean;
var
StreamSize: LongInt;
begin
try
Result := True;
try
StreamSize := (AStream.Size);
// AStream.Seek(0, soFromBeginning);
// AClient.IOHandler.LargeStream := True;
// AClient.IOHandler.SendBufferSize := 32768;
AClient.IOHandler.Write(LongInt(StreamSize));
AClient.IOHandler.WriteBufferOpen;
AClient.IOHandler.Write(AStream, 0, False);
AClient.IOHandler.WriteBufferFlush;
finally
AClient.IOHandler.WriteBufferClose;
end;
except
Result := False;
end;
end;
///
/// --------------- HELPER FUNCTIONS FOR FILES EXCHANGE ----------------
///
function ClientSendFile(AClient: TIdTCPClient; Filename: String): Boolean;
begin
AClient.IOHandler.LargeStream := True; // fully support large streams
Result := True;
try
AClient.IOHandler.WriteFile(Filename); // send file stream data
except
Result := False;
end;
end;
function ServerReceiveFile(AContext: TIdContext; ServerFilename: String;
var ClientFilename: String): Boolean;
var
// LSize: String;
AStream: TFileStream;
begin
try
Result := True;
AStream := TFileStream.Create(ServerFilename, fmCreate + fmShareDenyNone);
try
AContext.Connection.IOHandler.ReadStream(AStream);
finally
FreeAndNil(AStream);
end;
except
Result := False;
end;
end;
No hay comentarios:
Publicar un comentario