Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Internet
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 03-07-2011
maxinitto maxinitto is offline
Miembro
 
Registrado: may 2010
Posts: 45
Poder: 0
maxinitto Va por buen camino
Enviar y recibir archivos binarios sockets

Hola:

Despues de buscar , buscar y rebuscar no he tenido valor a encontrarme con un codigo que funcione, he probado muchos de muchas pags incluyendo esta pag y nada no tengo valor a enviar y recibir archivos con los componentes sockets que trae delphi 2009 por defecto, y bueno el caso es que yo quiero enviar desde el servidor al cliente un archivo .dat y bueno aver si alguien me puede proporcionar algun codigo que funcione por que es que ya me rindo me he tirado aqui dias y dias buscando hasta en pags rusas y nada xd bueno el fin de esto es que estoy haciendo una aplicacion client/server y tengo un filemanager entonces yo al extraer todos los archivos y carpetas de un directorio uso una funcion que extrae el icono que tiene cada archivo o carpeta y ese icono lo almaceno en un TImageList en el server entonces guardo los recursos del imagelist en un archivo .dat para enviar al cliente y cargarlo en otro imagelist y cargar cada icono a su respectivo directorio o archivo en el cliente y eso jejee....

PD: Solo encontre para la verdad un codigo pero solo envia .txt y de peso limitado...

Gracias de antemano.
Responder Con Cita
  #2  
Antiguo 04-07-2011
Avatar de Enan0
Enan0 Enan0 is offline
Miembro
 
Registrado: may 2004
Ubicación: Argentina
Posts: 565
Poder: 20
Enan0 Va por buen camino
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 es un FileListBox

  SendFile.InitialDir:=ExtractFilePath(ParamStr(0));
  SendFile.Execute;
  If SendFile.FileName<>'' then begin
    st:=TFileStream.Create(SendFile.FileName,fmopenread);
   // en esta linea envio el nombre del arhicvo y el tamaño. 
    Client.WriteLn('CMD#SNDFile#'+ExtractFileName(SendFile.FileName)+'#'+IntToStr(st.Size));
   // luego de enviar el mensaje, leo el Buffer para ver si respondio que podia recibir el archivo.
    if Client.ReadLn='RCVFile#Ready' then begin
      Try
// envio el Stream
        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 [-]

//las Variables RcvFile, FileName y Size son globales
procedure Server.ServerExecute(AThread: TIdPeerThread);
begin
if RcvFile then begin
  Try
    if st.Sizethen begin
      // Mientras que el tamaño del Stream sea menor que el Tamaño especificado sigue recibiendo como Stream
      AThread.Connection.ReadStream(st);
    end;
// Si el Tamaño de Stream es igual al que se habia informado al comienzo es que termino de Recibir y pone la clausula rcvFile en false
    if st.Size=size then begin
      RcvFile:=false;
      size:=0;
      st.free;
// Le dice al Cliente que el archivo fue ok.
      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.

Última edición por Enan0 fecha: 04-07-2011 a las 02:21:54.
Responder Con Cita
  #3  
Antiguo 04-07-2011
maxinitto maxinitto is offline
Miembro
 
Registrado: may 2010
Posts: 45
Poder: 0
maxinitto Va por buen camino
voy a probarlo tiene buena pinta es facil y comprensible el codigo aunque me hubiese gustado mejor el codigo para usarlo con los componentes socket que trae por defecto delphi 2009 y no los indy pero bueno aun asi te doy mil gracias saludos.

edito: que componente tengo que añadir de la paleta indy 10 para que no me tire errores de objeto no declarado?

Última edición por maxinitto fecha: 04-07-2011 a las 14:21:32.
Responder Con Cita
  #4  
Antiguo 04-07-2011
Avatar de Enan0
Enan0 Enan0 is offline
Miembro
 
Registrado: may 2004
Ubicación: Argentina
Posts: 565
Poder: 20
Enan0 Va por buen camino
Pero.. D2009 no trae los indy?.. yo habria jurado que si.

Bueno no cambia mucho, Siemplemente mandas un Stream.
si tengo un rato me fijo como seria.
Responder Con Cita
  #5  
Antiguo 04-07-2011
maxinitto maxinitto is offline
Miembro
 
Registrado: may 2010
Posts: 45
Poder: 0
maxinitto Va por buen camino
pues claro que trae los indy , los indy 10 pero te pregunto que, que componente de esa paleta tengo que añadir al form jejejej
Responder Con Cita
  #6  
Antiguo 04-07-2011
Avatar de Enan0
Enan0 Enan0 is offline
Miembro
 
Registrado: may 2004
Ubicación: Argentina
Posts: 565
Poder: 20
Enan0 Va por buen camino
Bueno yo utilize para ese ejemplo en uno. Un server IDTCPserver Que utiliza hilos, si no estas familiarizado con ellos podes usar un idSimpleServer.

y en otro proyecto un idTCPClient. este caso era porque usaba solo una conexion a un unico Server.

Las variantes te las dejo a vos.


Aclaracion:

el procedimiento Server.ServerExecute (...) es el OnExecute del componente idTCPServer.

espero que te quede claro y sino cualquier cosa decime.

ya que es lo mismo que enviar mensajes (TExto) solo que usamos el Procedimiento WriteStream() para enviar y el ReadStream() para recibir

saludos
Responder Con Cita
  #7  
Antiguo 04-07-2011
maxinitto maxinitto is offline
Miembro
 
Registrado: may 2010
Posts: 45
Poder: 0
maxinitto Va por buen camino
podias explicarme donde he de poner el codigo del cliente xk es que me tira errores jejejejejej perdona por ser pesadin jejejejejeje
Responder Con Cita
  #8  
Antiguo 04-07-2011
Avatar de Enan0
Enan0 Enan0 is offline
Miembro
 
Registrado: may 2004
Ubicación: Argentina
Posts: 565
Poder: 20
Enan0 Va por buen camino
Mira el codigo del cliente va en un Boton.. o una accion.. Simplemente eso.
si queres comparti tu codigo y que error te tira y asi puedo asistirte..

saludo
Responder Con Cita
  #9  
Antiguo 04-07-2011
maxinitto maxinitto is offline
Miembro
 
Registrado: may 2010
Posts: 45
Poder: 0
maxinitto Va por buen camino
es que mira el codigo conforme lo copio de aki me tira error, yo estoy modificando algunas cosas mira lo estoy dejando en un procedimiento

Código Delphi [-]
procedure EnviarArchivo(nombre : string);
var
  St:TFileStream;
begin
try

  If nombre <> '' then begin
    st:=TFileStream.Create(nombre ,fmopenread);
   // en esta linea envio el nombre del arhicvo y el tamaño.
    Form1.s3.Socket.WriteLn('CMD#SNDFile#'+ExtractFileName(nombre)+'#'+IntToStr(st.Size));
   // luego de enviar el mensaje, leo el Buffer para ver si respondio que podia recibir el archivo.
    if Form1.s3.Socket.ReadLn = 'RCVFile#Ready' then begin
      Try
// envio el Stream
        client.WriteStream(st,true,true,st.Size);
      except
      end;
    end else
      ShowMessage('Cant Send the File');
  end;
finally
  St.Free;
end;
end;

en esta linea no aparece ningun metodo ni procemiento que haga write stream, s3 es el nombre del componente IdTCPClient, ya que uso conexion inversa, luego entonces el codigo se usa al reves tu me entiendes... ejejej

Código Delphi [-]
client.WriteStream(st,true,true,st.Size);
Responder Con Cita
  #10  
Antiguo 04-07-2011
Avatar de Enan0
Enan0 Enan0 is offline
Miembro
 
Registrado: may 2004
Ubicación: Argentina
Posts: 565
Poder: 20
Enan0 Va por buen camino
Tendrias que Reemplazar CLIENT por S3 que es tu componente de Sockets
Responder Con Cita
  #11  
Antiguo 04-07-2011
maxinitto maxinitto is offline
Miembro
 
Registrado: may 2010
Posts: 45
Poder: 0
maxinitto Va por buen camino
eso es lo que hago pero me da error dice que el componente no cuenta con dicha propiedad o metodo
Responder Con Cita
  #12  
Antiguo 04-07-2011
Avatar de Enan0
Enan0 Enan0 is offline
Miembro
 
Registrado: may 2004
Ubicación: Argentina
Posts: 565
Poder: 20
Enan0 Va por buen camino
Mira te recomiendo que busques en la lista de metodos y verifica cual envia un Stream. ya que yo no dispongo Delphi 2009 pero los metodos no varian mucho.

saludos
Responder Con Cita
  #13  
Antiguo 05-07-2011
maxinitto maxinitto is offline
Miembro
 
Registrado: may 2010
Posts: 45
Poder: 0
maxinitto Va por buen camino
bueno pues nada aver si alguien me puede ayudar , que aun sigo con mi problema de no tener un codigo para enviar archivos y recibirlo
Responder Con Cita
  #14  
Antiguo 05-07-2011
beginner01 beginner01 is offline
Miembro
NULL
 
Registrado: mar 2011
Ubicación: República Dominicana
Posts: 181
Poder: 14
beginner01 Va por buen camino
saludos.

revisa este enlace a ver si es lo que nesesitas.
Responder Con Cita
  #15  
Antiguo 05-07-2011
maxinitto maxinitto is offline
Miembro
 
Registrado: may 2010
Posts: 45
Poder: 0
maxinitto Va por buen camino
hola:

ese codigo lo he probado y no va tira error de socket o no se....

aki pongo una img del error:

http://imageshack.us/photo/my-images...inttulocd.jpg/

Última edición por maxinitto fecha: 05-07-2011 a las 22:19:40.
Responder Con Cita
  #16  
Antiguo 06-07-2011
beginner01 beginner01 is offline
Miembro
NULL
 
Registrado: mar 2011
Ubicación: República Dominicana
Posts: 181
Poder: 14
beginner01 Va por buen camino
no puedo visualizar bien la imagen pero
hay varias razones por que se produce el "Asynchronous socket error".

yo ya probe los ejemplos y funcionan bien

pienso que no iniciaste el servidor y por eso te da el error debes ejecutarlo y darle a start server y luego en el cliente a connect
y asi deberia funcionar sin problemas.

si continua el error deberias decir donde te da el error.
Responder Con Cita
  #17  
Antiguo 06-07-2011
maxinitto maxinitto is offline
Miembro
 
Registrado: may 2010
Posts: 45
Poder: 0
maxinitto Va por buen camino
pero si asi es como lo hago yo jejejejejejej mira aqui te pongo otra captura en otro servidor

Responder Con Cita
  #18  
Antiguo 06-07-2011
beginner01 beginner01 is offline
Miembro
NULL
 
Registrado: mar 2011
Ubicación: República Dominicana
Posts: 181
Poder: 14
beginner01 Va por buen camino
así es difícil saber porque te da el error solo se me ocurre que son problemas con los puertos. prueba cambiando los puertos de
serversocket2 y clientsocket2
Responder Con Cita
  #19  
Antiguo 06-07-2011
maxinitto maxinitto is offline
Miembro
 
Registrado: may 2010
Posts: 45
Poder: 0
maxinitto Va por buen camino
mira te explico, cogi el codigo ese y lo adapte a mi programa ya que mis socket si funcionan....

desde el cliente envio un mensaje al recibir el servidor dicho mensaje ejecuta esto

Código Delphi [-]
EnviarArchivo('ImageList.dat');

procedure EnviarArchivo(nombre : string);
var
 FileSize : String;
begin

 Form1.s.Socket.SendText('FILE!'+nombre);
 sleep(2000); // Need to sleep so the other end has time to process the commands
 Form1.FStream := TFileStream.Create(nombre, fmopenread); // Stream created just to Calculate size
 FileSize := inttostr(Form1.FStream.Size);
 Sleep(2000);
 Form1.s.Socket.SendText('SIZE!' + FileSize); // Sends filesize through primary socket
 Form1.FStream.Position := 0;
 Form1.FStream.Free;
 sleep(2000);
 Form1.s2.Socket.SendStream(TFileStream.Create(nombre, fmopenRead));

end;

que si te fijas es el codigo del boton del cliente del codigo que me pasastes ese, el de enviar arhivo.

aki el onread del socket1 y el del socket 2

Código Delphi [-]
procedure TForm2.cClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
 IncommingText, StrippedData, CommandName: string;
begin

     IncommingText := PansiChar(socket.ReceiveText);
     StrippedData := copy(IncommingText,6,length(IncommingText) );
     CommandName := copy(IncommingText,0,5);
     FileSizes := StrippedData;
     if CommandName = 'FILE!' then
        FStream := TFileStream.Create('ImageList.dat', fmCREATE or fmOPENWRITE and fmsharedenywrite);

end;

procedure TForm4.c2ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
  textorecibido : String;
  res , res2: TStringDynArray;
  lvitem : TListItem;
  i , j : integer;
  Buffer: array [0..9999] of Char;
  IncommingLen, RecievedLen: integer;
  Filepath: string;
begin

if TV_Opciones.Selected.Text = 'Archivos' then
begin

  if Pos('CojoUnidades', textorecibido) = 1 then
  begin
    res := Explode('|', textorecibido);
    for i := 1 to high(res) do
      CB_Unidades.Items.Add(res[i]);
  end;

if Pos('Directorios', textorecibido) = 1 then
begin
    res := Explode('---', textorecibido);

    for i := 1 to high(res)-1 do
    begin
      res2 := Explode('|', res[i]);
      lvitem := LV_ArchivosRecibidos.Items.Add;
      lvitem.Caption := res2[0];
      lvitem.SubItems.add(res2[1]);
      if res2[1] = 'Carpeta' then
        lvitem.ImageIndex := 0
      else
        lvitem.ImageIndex := StrToInt(res2[2]);
    end;

  end;
  exit;

end;



   Timer1.Enabled := True;
   IncommingLen := socket.ReceiveLength;

    // Sets a String Filepath for the actual directory with the filename so that the shellexecute can run this after
    while IncommingLen > 0 do
    begin
       RecievedLen := socket.ReceiveBuf(Buffer, Sizeof(Buffer));
       // Changes the size of RecievedLen by the amount of incoming data recieved
    if RecievedLen <= 0 then
    // Small part of the code where once the buffer reaches 0 the code will exit
       Break
    else
    FStream.Write(Buffer, RecievedLen);

    // through the primary socket Also this line increases the progess indicator bar
    if FStream.Size >= StrToInt(FileSizes) then
    // Onces the stream size begins to reach the size which was sent before sending the file then this
    begin
     // procedure will start
       FStream.Free;
       Timer1.Enabled := False;
       TimeTaken := 0;
       Break;                                                                         // This line basically executes any file using the extension from the windows ini files.
    end;
    end;

end;

bueno pues no se que hago mal xk me llega el archivo vacio con 0 kb , pero ahora el error de antes no lo da, ese error se debia a que los sockets no estaban conectados, bueno aver si me pueden echar un cable por que por lo visto hay mas de uno que le cuesta y esto que digo de que le cuesta sabe para quien va jejeje saludos
Responder Con Cita
  #20  
Antiguo 07-07-2011
maxinitto maxinitto is offline
Miembro
 
Registrado: may 2010
Posts: 45
Poder: 0
maxinitto Va por buen camino
Ala ya lo solucione el problema estaba en la desordenada ejecucion del codigo aqui adjunto el .zip con el proyecto por que seguro que a alguien le sera de utilidad y nada tema cerrado gracias por toda la ayuda.
Archivos Adjuntos
Tipo de Archivo: zip Socket.zip (13,3 KB, 106 visitas)
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Enviar y recibir archivos con TCPCliente y TCPServer victork_py Internet 4 16-07-2015 01:42:01
archivos binarios kazcote Varios 5 05-12-2005 04:02:35
Enviar y Recibir Archivos (Codigo para hacerlo) juliopag1 Internet 0 17-05-2005 21:22:44
¿Cómo puedo enviar y recibir archivos vía IRC con el componente TIdIRC? DarkByte Internet 4 26-06-2004 17:54:05
archivos exe y/o binarios fcran Varios 2 26-06-2003 14:34:21


La franja horaria es GMT +2. Ahora son las 08:00:07.


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
Copyright 1996-2007 Club Delphi