Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Internet (https://www.clubdelphi.com/foros/forumdisplay.php?f=3)
-   -   Enviar archivo por socket. 'TStream' y 'TFileStream' Incompatibles. (https://www.clubdelphi.com/foros/showthread.php?t=11914)

Sr_Sombrero 29-06-2004 19:18:24

Enviar archivo por socket. 'TStream' y 'TFileStream' Incompatibles.
 
Estoy tratando de transferir un archivo a través de una conexión por socket.

Programo una "Console Application" por lo que no puedo recurrir a los componentes sockets que trae Delphi, así que uso una Librería WinSock que funciona casi igual que los TServerSocket y TClientSocket.

El problema surge cuando quiero enviar un archivo usando un código similar a este:

Código:

ClientSocket2.Socket.SendStream (TFileStream.Create (strFile, fmOpenRead or fmShareDenyWrite));
Esto funciona en los componentes sockets que trae Delphi, pero en el caso de la librería que uso me da el siguiente error al compilar:

"Incompatible types: 'TStream' and 'TFileStream'"

La primera solución que se me ocurre es (si se puede) transformar el TFileStream a TStream. ¿Cómo lo hago?

La segunda solución podría ser enviar el archivo de otra manera ¿SendBuffer serviría?

Gracias de antemano :)

roman 29-06-2004 20:15:35

Cita:

Empezado por Sr_Sombrero
Programo una "Console Application" por lo que no puedo recurrir a los componentes sockets que trae Delphi

¿Y por qué no?

El hecho de que no dispongas de un formulario para insertar los componentes no te impide usarlos, es sólo que tienes que crearlos tú mismo, por ejemplo:

Código Delphi [-]
var
  Server: TServerSocket;

begin
  Server := TServerSocket.Create(nil);
end;

Y acordarte de destruirlos con

Código Delphi [-]
Server.Free;

// Saludos

jachguate 29-06-2004 21:08:52

Cita:

Empezado por Sr_Sombrero
Programo una "Console Application" por lo que no puedo recurrir a los componentes sockets que trae Delphi, así que uso una Librería WinSock que funciona casi igual que los TServerSocket y TClientSocket.

Ya te ha dicho román que si es posible, y creo que sería lo mejor (mejor si con las INDY, desde mi punto de vista).

Cita:

Empezado por Sr_Sombrero
Esto funciona en los componentes sockets que trae Delphi, pero en el caso de la librería que uso me da el siguiente error al compilar:

"Incompatible types: 'TStream' and 'TFileStream'"

La primera solución que se me ocurre es (si se puede) transformar el TFileStream a TStream. ¿Cómo lo hago?

Hola. Habría que ver la sentencia donde te da el error, y si es en una llamada a procedimiento o función, ver cómo está declarada. Lo cierto es que un TFileStream si es un TStream, puesto que deriva de él, por lo que no necesita de ninguna transformación para ser un TStream.

Hasta luego.

;)

Sr_Sombrero 29-06-2004 21:28:03

Cita:

El hecho de que no dispongas de un formulario para insertar los componentes no te impide usarlos, es sólo que tienes que crearlos tú mismo.
Todos los días se aprende algo nuevo :) , de todos modos si puedo usar la librería que tengo es mejor porque pesa el 10% de las originales.


Cita:

Lo cierto es que un TFileStream si es un TStream
Si, eso lo investigue en el libro de Cantú, por eso no entinedo porque no anda.


Cita:

Habría que ver la sentencia donde te da el error, y si es en una llamada a procedimiento o función, ver cómo está declarada.
Voy a ver si puedo elaborar un poco más la pregunta.

¿y mandarlo como sendBuffer? ¿se puede?

Muchas gracias :)

jachguate 29-06-2004 21:33:55

Cita:

Empezado por Sr_Sombrero
¿y mandarlo como sendBuffer? ¿se puede?

Depende del tamaño del archivo, pues tenes que subirlo todo a memoria y tenerlo en un vector o estructura similar. Tanto para enviarlo como para recibirlo.

Algo como:

Código Delphi [-]
Var
  archivo: Array[1..1048576] of byte; {archivo de 1 Mb}

Begin
  // lee primero el archivo al arreglo y luego:
  ObjetoOLibreria.SendBuffer(archivo[0], length(archivo));
end;

Hasta luego.

;)

roman 30-06-2004 02:53:47

Por cierto, aunque decidas no usar las componentes mencionadas, te comento que no sólo puedes usarlas en una aplicación de consola cómo te dije, sino que además puedes agregar un DataModule a tu proyecto en donde sí puedes colocar las componentes como si de un Form se tratara y modificar sus propiedades en el inspector de objetos.

// Saludos

Sr_Sombrero 01-07-2004 07:45:37

Finalmente encontré este código para enviar y recibir archivos como buffer.
Lo copio para futuras consultas ;)
Sacado de una página que ya no existe (delphi.owns.it).

Código Delphi [-]
procedure TClientSocket.ReceiveFile(FileName: string);
var
  Data: string;
  Buffer: pchar;
  BinaryFile: file of char;
  BinaryFileSize, BytesRead: integer;
begin
  Idle(0);
  Data := ReceiveString;
  BinaryFileSize := StrToInt(Data);
  Idle(0);
  AssignFile(BinaryFile, FileName);
  ReWrite(BinaryFile);
  while FileSize(BinaryFile) < BinaryFileSize do
  begin
    Sleep(1);
    BytesRead := ReceiveLength;
    if BytesRead > 0 then
    begin
      GetMem(Buffer, BytesRead);
      try
        ReceiveBuffer(Buffer^, BytesRead);
        BlockWrite(BinaryFile, Buffer^, BytesRead);
      finally
        FreeMem(Buffer);
      end;
    end;
  end;
  CloseFile(BinaryFile);
end;

procedure TClientSocket.SendFile(FileName: string);
var
  BinaryFileSize, BytesRead: integer;
  Buffer: pchar;
  BinaryFile: file of char;
  BinaryFileHandle: THandle;
begin
  BinaryFileHandle := CreateFile(pchar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL OR FILE_FLAG_NO_BUFFERING, 0);
  BinaryFileSize := GetFileSize(BinaryFileHandle, nil);
  CloseHandle(BinaryFileHandle);
  AssignFile(BinaryFile, FileName);
  Reset(BinaryFile);
  SendString(inttostr(BinaryFileSize));
  Sleep(500);
  repeat
    Sleep(1);
    GetMem(Buffer, 2048);
    try
      BlockRead(BinaryFile, Buffer^, 2048, BytesRead);
      SendBuffer(Buffer^, BytesRead);
    finally
      FreeMem(Buffer);
    end;
  until BytesRead < 2048;
  CloseFile(BinaryFile);
end;

Saludos :)


La franja horaria es GMT +2. Ahora son las 20:43:36.

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