Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Internet (https://www.clubdelphi.com/foros/forumdisplay.php?f=3)
-   -   Enviar y recibir archivos con TCPCliente y TCPServer (https://www.clubdelphi.com/foros/showthread.php?t=43065)

victork_py 01-05-2007 00:12:46

Enviar y recibir archivos con TCPCliente y TCPServer
 
Hola a todos, estoy programando una aplicación que debe enviar y recibir archivos con otra PC conectada en la misma red.

Estoy programando con Turbo Delphi Explorer, y en esa ya no estan los componentes ServerSocket y ClientSocket, a cambio de eso estan TCPServer y TCPClient.

Buscando en google, encuentro ejemplos con ServerSocket y ClientSocket, pero los de TCPServer y TCPClient encuentro muy pocos, y la mayoria son ejemplos de chat.

Para el envío de archivo uso el método SendStream del TCPClient, y supongo que de alguna manera puedo recibirlo con el TCPServer, pero no encuentro la forma de recibirlo, pues no hay un método para recibir un stream.

Podrían darme una pista de como hacer para recibir el archivo con TCPServer?

seoane 01-05-2007 02:54:20

1 Archivos Adjunto(s)
Una posible solución es enviar el archivo y luego desconectar, de esta forma solo tendríamos que leer, en el lado del servidor, hasta que la conexión se cierre.

Por ejemplo:
Código Delphi [-]
const
  BufferSize = 32 * 1024;

// En el evento OnAccept del TTCPServer (BlockMode = bmThreadBlocking)
procedure TfrmMain.ServidorAccept(Sender: TObject;
  ClientSocket: TCustomIpClient);
var
  Buffer: PByte;
  Recibidos: Integer;
begin
  // La primera linea que recibimos es la ruta donde guardar el archivo
  with TFileStream.Create(ClientSocket.Receiveln, fmCreate) do
  try
    // Reservamos memoria para el buffer
    GetMem(Buffer,BufferSize);
    try
      // Recibimos los datos del archivo hasta que se cierre la conexion
      Recibidos:= ClientSocket.ReceiveBuf(Buffer^,BufferSize);
      while Recibidos > 0 do
      begin
        // Guardamos los datos recibidos en el archivo
        WriteBuffer(Buffer^,Recibidos);    
        Recibidos:= ClientSocket.ReceiveBuf(Buffer^,BufferSize);
      end;
    finally
      // Liberamos la memoria
      FreeMem(Buffer);
    end;
  finally
    Free;
  end;
end;
El cliente lo implemento dentro de un thread, ya que voy a colocar la propiedad BlockMode = bmBlocking y no quiero que se me bloquee el resto de la aplicación. Aunque puede parecer complicado, esto nos permitirá mandar varios archivos a la vez y también cancelar el envió antes de que termine.

El thread cliente, que yo llamare TEnvio, lo implemento asi:
Código Delphi [-]
// Debajo de interface, junto a la definicion del formualrio
 TEnvio = class(TThread)
  private
    FCliente: TTCPClient;
    FLocalFile: String;
    FRemoteFile: String;
  protected
    procedure Execute; override;
  public
    constructor Create(LocalFile,RemoteFile,Host,Port: String);
    destructor Destroy; override;
  end;


// Debajo de implementation
{ TEnvio }

constructor TEnvio.Create(LocalFile,RemoteFile,Host,Port: String);
begin
  inherited Create(FALSE);
  // Le indicamos que se destruya al termianr
  FreeOnTerminate:= TRUE;
  FLocalFile:= LocalFile;
  FRemoteFile:= RemoteFile;
  // Creamos un TTCPClient
  FCliente:= TTCPClient.Create(nil);
  FCliente.RemoteHost:= Host;
  FCliente.RemotePort:= Port;  
  FCliente.BlockMode:= bmBlocking;
end;

destructor TEnvio.Destroy;
begin
  // Destruimos el TTCPClient
  FCliente.Free;
  inherited;
end;

procedure TEnvio.Execute;
var
  Buffer: PByte;
  Leidos: Integer;
begin
  inherited;
  // Abrimos el archivo como solo lectura
  with TFileStream.Create(FLocalFile,fmOpenRead or fmShareDenyWrite) do
  try
    // Reservamos memoria para el buffer
    GetMem(Buffer,BufferSize);
    try
      // Intentamos conectar con el servidor
      FCliente.Active:= TRUE;
      try
        // Enviamos la ruta donde se debe guardar el archivo
        FCliente.Sendln(FRemoteFile);
        // En este bucle enviamos el archivo
        Leidos:= Read(Buffer^,BufferSize);
        while (Leidos > 0) and not Terminated do
        begin
          FCliente.SendBuf(Buffer^,Leidos);
          Leidos:= Read(Buffer^,BufferSize);
        end;
      finally
        // Cerramos la conexion
        FCliente.Active:= FALSE;
      end;
    finally
      FreeMem(Buffer);
    end;
  finally
    Free;
  end;
end;

Un ejemplo de como usar lo anterior:
Código Delphi [-]
var
  Envio: TEnvio;
begin
  with TOpenDialog.Create(nil) do
  try
    if Execute then
    begin
      Envio:= TEnvio.Create(Filename, 'C:\' +  ExtractFileName(Filename),
        txtHost.Text, '2000');
    end;
  finally
    Free;
  end;
end;
En cualquier momento podemos cancelar la transmisión utilizando "Envio.Terminate". Pero te dejo a ti escoger cuando y donde utilizar esa opción. Otras mejoras pueden ser que la ruta del archivo remoto sea relativa y no absoluta, por motivos de seguridad, o enviar junto con el archivo su hash md5 para comprobar que ha llegado bien. Pero eso lo podemos dejar para mas adelante ...

Aquí te dejo el proyecto envuelto para regalo ... :p

charley 07-07-2015 03:04:07

Enviar y recibir archivos con TCPCliente y TCPServer
 
amigos no logro enviar mas de un archivo tanto con ese codigo como con otro que tengo, estoy desesperado, ayuda por favorrrrrrrrrrrrrr!!!!!

nlsgarcia 07-07-2015 04:25:23

charley,

¡Bienvenido al Club Delphi! :D

Te sugiero revisar la Guía de estilo de los foros, recomendada a todos los nuevos ingresos al Club Delphi.

¡Gracias por tu cooperación! :) ^\||/

Nelson.

Casimiro Notevi 16-07-2015 01:42:01

Cita:

Empezado por charley (Mensaje 494503)
necesito poder mandar varios de un tiro, lo he intentado de varias formas y nada...soy un novatón.
Saludos y gracias de antemano

Por favor, lee la guía de estilo de clubdelphi, que te ha recomendado el compañero. Gracias por tu colaboración.


La franja horaria es GMT +2. Ahora son las 08:49:32.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi