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 13-07-2010
Avatar de Faust
Faust Faust is offline
Miembro
 
Registrado: abr 2006
Ubicación: México D.F.
Posts: 930
Poder: 19
Faust Va por buen camino
Explicación uso TCPServer, TCPCLient, UDPClient, UDPServer ¿para qué sirven??

Hola compañeros del foro, quisiera si alguien tiene tiempo y desea compartir sus conocimientos que me explicara el uso, funcionamiento y en que casos se usan los componentes Indy TCPServer, TCPClient, UDPServer, UDPClient por favor.

Sé que algunos me contestarán que busque en google o en la documentación de Indy, pero quisiera una explicación más amena y menos árida que la que dan en otros sitios.

Desde ya muchas gracias.
__________________
Herr Heins Faust
Responder Con Cita
  #2  
Antiguo 13-07-2010
Rockin Rockin is offline
Miembro
 
Registrado: may 2003
Ubicación: Málaga
Posts: 264
Poder: 22
Rockin Va por buen camino
Buenas el uso es variado, yo por ejemplo uso los componentes UDPClient y UDPServer, para comunicarme con mi centralita por medios de sockets UDP que son los que usan por defecto mi centralita.

Los TCP los uso para un chat interno, puedes enviar ficheros, etc...

La idea de estos componentes es la comunicación entre una parte servidora y una cliente, los TCP te aseguran la conexión y la integridad de la comunicacion mientras que los UDP no te la aseguran. Además permite broadcast para enviar paquetes a toda una red.

Espero haberte aclarado algo.

Saludos.
Responder Con Cita
  #3  
Antiguo 13-07-2010
Avatar de Faust
Faust Faust is offline
Miembro
 
Registrado: abr 2006
Ubicación: México D.F.
Posts: 930
Poder: 19
Faust Va por buen camino
Gracias por la explicación Rockin...

Ahora me surgen algunas dudas.

Necesito tranferir archivos desde varias PC's conectadas a internet a mi servidor, por alguna razón en mi trabajo no quieren que sea por medio de ftp... asi que: ¿podría utilizar TCPServer y TCPClient? ¿TCPServer estaría en el servidor con IP fija en mi oficina y TCPClient en cada una de las PC's que le enviarán los archivos a TCPServer en mi oficina? Si las respuestas a mis preguntas anteriores son si... entonces ¿La PC de mi ofinina sería el server de las PC's fuera de mi oficina que serían las client?

Gracias de antemano y disculpen que sea tan preguntón.
__________________
Herr Heins Faust
Responder Con Cita
  #4  
Antiguo 14-07-2010
Rockin Rockin is offline
Miembro
 
Registrado: may 2003
Ubicación: Málaga
Posts: 264
Poder: 22
Rockin Va por buen camino
No se cual es la razon por la que no quieren que sea por FTP, pregunta si puedes hacerlo por SFTP, es una tonteria tener que programar esto cuando hay muchismo software gratuito para ello.

Podrias usar TCPClient y TCPServer para mandar ficheros. me parece que era con el metodo TCPClient.WriteFile o algo así.

Busca por los foros o en google.

Saludos.
Responder Con Cita
  #5  
Antiguo 15-07-2010
Avatar de sintecsl
sintecsl sintecsl is offline
Miembro
 
Registrado: jun 2008
Ubicación: Barcelona - Spain
Posts: 40
Poder: 0
sintecsl Va por buen camino
Creo que la idea de tu empresa es que los enlaces no sean públicos. Es decir estilo VPN.

En mi caso cree hace algunos años una VPN y me puedo conectar con cualquier PC utilizando la RED de Internet pero sin ser visible a nivel público.

Para esto te será muy útil los TCP de indy. Que sepas que el que actua como server lo hace en multiproceso o multi-hilo. Solo tienes que crear en el TCPServer (añadir) instrucciones. Lo recomendable de entrada es que al realizar la acción connect envies un password que te autentifique en el servidor (Que tenga almenos 200 carácteres encriptados) eso evita cualquier hacker al azar.

Si lo que quieres es enviar solo ficheros no te compliques con los indy y utiliza TSock u otro objeto que ya los hay y que implementan correctamente esa situación.

Saludos
__________________
www.sintecsl.es
Responder Con Cita
  #6  
Antiguo 15-07-2010
Avatar de Faust
Faust Faust is offline
Miembro
 
Registrado: abr 2006
Ubicación: México D.F.
Posts: 930
Poder: 19
Faust Va por buen camino
Cita:
Empezado por sintecsl Ver Mensaje
Creo que la idea de tu empresa es que los enlaces no sean públicos. Es decir estilo VPN.

En mi caso cree hace algunos años una VPN y me puedo conectar con cualquier PC utilizando la RED de Internet pero sin ser visible a nivel público.

Para esto te será muy útil los TCP de indy. Que sepas que el que actua como server lo hace en multiproceso o multi-hilo. Solo tienes que crear en el TCPServer (añadir) instrucciones. Lo recomendable de entrada es que al realizar la acción connect envies un password que te autentifique en el servidor (Que tenga almenos 200 carácteres encriptados) eso evita cualquier hacker al azar.

Si lo que quieres es enviar solo ficheros no te compliques con los indy y utiliza TSock u otro objeto que ya los hay y que implementan correctamente esa situación.

Saludos
Creo que por ahí va la cosa... la cosa es no solo enviar archivos, sino también comandos a la aplicación cliente para que responda a peticiones del server...

Ya empecé algo y si tengo alguna duda paso por acá...

¿cómo está lo de el password al connect y la encriptación? ¿tienes algún enlace a algún ejemplo o puedes proporcionármelo?

Gracias de antemano amigos
__________________
Herr Heins Faust
Responder Con Cita
  #7  
Antiguo 19-07-2010
Avatar de sintecsl
sintecsl sintecsl is offline
Miembro
 
Registrado: jun 2008
Ubicación: Barcelona - Spain
Posts: 40
Poder: 0
sintecsl Va por buen camino
Password y encriptación

Por internet ya existe muchos ejemplo prácticos e ilustrativos. Busca en google entrelazando las dos palabras y delphi y seguro que encuentras miles de enlaces en tu idioma.

Por otro lado si dominas lo indy u otro VCL, pues es fácil. Existe la instrucción OnConnect en el IdServer, yo tengo esto :
Código Delphi [-]
procedure TServerForm.ServerConnect(AThread: TIdPeerThread);
Var
   Name,
   Pass : String;
begin
     //Cuando se conecta un cliente se notifica
     Memo1.Lines.Add('Conectado : '
                     +' <- IP:Puerto : '+AThread.Connection.Socket.Binding.PeerIP
                     +':'+IntToStr(AThread.Connection.Socket.Binding.PeerPort));
     //Leemos nombre del conectado
     Name:=AThread.Connection.ReadLn();
     //Leemos el password (Clave) de la red de conexión
     Pass:=AThread.Connection.ReadLn();
     If Not (Pass=Usuario.Passw) Then
       Begin
            AThread.Connection.Socket.Close;
            Memo1.Lines.Add('Usuario o intruso rechazado')
       End
     Else Memo1.Lines.Add('Usuario '+Name+' identificado correctamente')
end;
A parte de esto determino el tamaño de buffer etc, para optimizar los envíos y recepciones.

Te pongo lo que tengo en el IdCliente al intentar conectar. Piensa que hay muchas llamadas a otros procedimientos que no bienen al caso.
Código Delphi [-]
procedure TClienteForm.ConectarClick(Sender: TObject);
Var
   Sl : TStringList;
   IP, Puerto : String;
begin
     If EnEjecucion Then Exit; //Para no solapar los procesos
     EnEjecucion:=True; //Prevenimos rellamadas
     try
     If Cliente.Connected Then
       Begin
            StatusServer.Panels.Items[0].Text:='Desconectando';
            Cliente.Disconnect;
            Conectar.Checked:=False;
            StatusServer.Panels.Items[0].Text:='Desconectado';
            //Vaciamos listas server
            DirsServer.Items.Clear;
            FilesServer.Items.Clear;
            EnEjecucion:=False;
            Exit //Salimos
       End;
     //Buscamos la IP del servidor actualizada
      StatusServer.Panels.Items[0].Text:='Conectando ...';
      Sl:=TStringList.Create;
      Sl.Text:=Servidores.Text;
      Sl.Text:=AnsiReplaceText(Sl.Text,'#',#13);
      If (Sl.Text='')Or(Sl.Count<3) Then
       Begin //No hay servidor
            MensageError('No hay servidor registrado');
            Sl.Free;
            StatusServer.Panels.Items[0].Text:='Desconectado';
            EnEjecucion:=False;
            Exit //Salimos
       End;
      IP:=SL.Strings[1]; //2ª línea es el IP
      Puerto:=SL.Strings[2]; //3ª línea es el Port de acceso al server
      SL.Free;
      Cliente.Disconnect; //Por si acaso
      Cliente.Host:=IP;
      Cliente.Port:=StrToInt(Puerto);
      Try
      Cliente.Connect;
      Except   //Silenciamos el mensaje de error
        If Not Cliente.Connected Then
          Begin
               StatusServer.Panels.Items[1].Text:='ERROR AL CONECTAR CON EL SERVER';
               Exit //Obliga a que salte al Finally
          End
      End;
     If Cliente.Connected Then
       Begin
            //Nos identificaremos con el nombre de usuario y el password
            //ya que lo está esperando el server
            Cliente.WriteLn(Usuario.Name);
            Cliente.WriteLn(Usuario.Passw); //IMPORTANTE SI NO COINCIDEN ERROR
            If Cliente.Connected Then //No rechazó la conexión
              Begin
                  TamPaqueteChange(Self);
                  Cliente.WriteLn('DAMEDISCOSACTIVOS');
                  Sl:=TStringList.Create;
                  Cliente.ReadStrings(Sl);
                  //Añadimos unidades y dirs favoritos del server
                  UnidadesServer.Items.Text:=Sl.Text+
                        ConfigCliente.ListaDirsServer.Items.Text;;
                  Sl.Free;
                  UnidadesServer.ItemIndex:=0;
                  //si no hay un dir de arranque preferido
                  //comenzamos por la 1ª unidad
                  If ConfigCliente.Memo1.Lines.Text='' Then
                     DirRootServer:=UnidadesServer.Text
                  Else DirRootServer:=ConfigCliente.Memo1.Lines.Strings[0];
              End
       End;
     finally
     Conectar.Checked:=Cliente.Connected; //Se verifica si realmente conectó
     If Cliente.Connected Then
        StatusServer.Panels.Items[0].Text:='Conectado'
     Else StatusServer.Panels.Items[0].Text:='Desconectado';
     EnEjecucion:=False;
     End
end;
En negrita te dejo lo que te interesa.
__________________
www.sintecsl.es

Última edición por nlsgarcia fecha: 15-07-2015 a las 23:21:40. Razón: Sintaxis Delphi
Responder Con Cita
  #8  
Antiguo 19-07-2010
Avatar de Faust
Faust Faust is offline
Miembro
 
Registrado: abr 2006
Ubicación: México D.F.
Posts: 930
Poder: 19
Faust Va por buen camino
Muy ilustrativo amigo Sintecsl...

Me gustó mucho tu ejemplo, me ha aclarado algunas cosas, solo algunas preguntas... en cuanto al tamaño del buffer para el envío y recepción ¿te refieres a la propiedad RecvBufferSize y SendBufferSize del client? ¿el server tiene alguna parecida o se ajusta al client?, ¿este tamaño puede ser modificado una vez que se ha conectado el cliente?

Bueno... creo que ya he dado mucha lata.

Por último, veo que eres nuevo en el club y sería bueno que cooperaras más seguido con nosotros y también a nombre del club te ofrezco el apoyo de los demás compañeros .

Gracias de antemano y buen inicio de semana.
__________________
Herr Heins Faust
Responder Con Cita
  #9  
Antiguo 20-07-2010
Avatar de sintecsl
sintecsl sintecsl is offline
Miembro
 
Registrado: jun 2008
Ubicación: Barcelona - Spain
Posts: 40
Poder: 0
sintecsl Va por buen camino
Cita:
Empezado por Faust Ver Mensaje
Muy ilustrativo amigo Sintecsl...

Me gustó mucho tu ejemplo, me ha aclarado algunas cosas, solo algunas preguntas... en cuanto al tamaño del buffer para el envío y recepción ¿te refieres a la propiedad RecvBufferSize y SendBufferSize del client? ¿el server tiene alguna parecida o se ajusta al client?, ¿este tamaño puede ser modificado una vez que se ha conectado el cliente?

Bueno... creo que ya he dado mucha lata.

Por último, veo que eres nuevo en el club y sería bueno que cooperaras más seguido con nosotros y también a nombre del club te ofrezco el apoyo de los demás compañeros .

Gracias de antemano y buen inicio de semana.

A tu pregunta el buffer, la respuesta es que si se puede manipular tanto en el cliente (lo mas facil) como en el server.
En la propiedad del buffer cuando te pasa la variable el cliente se establece para dicha conexión esa variable de forma automática en Indy.

En el server si quieres cambiar ese buffer puedes poner una instrucción o comando :
Código Delphi [-]
procedure TServerForm.ServerCAMBIATAMANOBUFFERCommand(ASender: TIdCommand); 
begin 
     // Comando CAMBIATAMANOBUFFER 
     // Pondremos el tamaño de buffer que nos pase para la 
     // conexión actual, importante para sincronizar mejor 
     // los envíos y recepciones. 
     // Nos tiene que enviar un Integer solamente, ya que lo 
     // consideraremos de forma simetrica Envío <-> Recepción 
     Try 
     ASender.Thread.Connection.RecvBufferSize:=ASender.Thread.Connection.ReadInteger(); 
     ASender.Thread.Connection.SendBufferSize:=ASender.Thread.Connection.RecvBufferSize; 
     Except //Por si se desmadra el tema capturamos excepciones 
     End 
     // End 
end;
Esto es útil porque en mi caso envío/recepciono de forma comprimida ficheros.

Y establezco la compresión al conectar con esta instrucción :
Código Delphi [-]
procedure TServerForm.ServerNIVELCOMPRESIONCommand(ASender: TIdCommand); 
begin 
     //Cambiamos la forma de comprimir No, Fast, Best, Max 
     NivelCompress:=TZCompressionLevel(ASender.Thread.Connection.ReadInteger()); 
     //Colocamos en el ini el nivel de compresión 
     FormStorage1.StoredValues.Values['NivelCompresion'].Value:= 
               Integer(NivelCompress); 
     FormStorage1.StoredValues.SaveValues; 
end;
Lo cual me permite ajustar el ancho de banda de conexión.

Por otro lado, en el envío/recepción de ficheros determino el buffer a la mitad del que tiene cada conexión (el buffer está guardado en cada variable tipo hilo (ASender)). Esto es motivo para evitar desbordamientos en ficheros muy comprimidos y que superan el tamaño original, lo cual te daría errores insalvables.

Como ejemplo un boton :

EL CLIENTE :
Código Delphi [-]
procedure TCopiaFiles.CopiaAlServer(const Origen, Destino: String); 
Var 
   Error, TamanoPaq, NPaq, Leidos, Escritos, x, Parar : Integer; 
   FHandle : Integer; 
   Buf, BufOut : Pointer; 
   SFile : TFileStream; 
begin 
     try //Capturamos errores graves 
     If (Not Cliente.Connected)Or(EnEjecucion)Or(PararEnvioRecepcion) Then Exit; 
     EnEjecucion:=True; //Prevenimos rellamadas 
     LimpiaPantalla; //Ponemos la pantalla en estado inicial 
     Enviando; // Retardo para simular y animación 
     Cliente.Writeln('COPIAFILEDECLIENTE'); //ENVIAR UN FICHERO AL SERVER 
     // El fichero que se enviará en destino 
     Cliente.Writeln(Destino); 
     // Nos tiene que retornar primero si hay error 
     Recibiendo; // Retardo para simular y animación 
     Error:=Cliente.ReadInteger(); 
     // Si el error simplemente en el 13000 significa que se debe confirmar 
     // la ejecución, puesto que existe en destino (Server) 
     // Los otros errores son insalvables, como que el directorio no existe 
     // o no lo puede crear. 
     If Error=13000 Then  // Si existe en destino 
      Begin 
       Parar:=0; 
       If Sobreescritura Then //Activamos confirmación 
          Parar:=Application.MessageBox('¿ SOBREESCRIBIR ?','ATENCIÓN', 
                                        MB_YESNOCANCEL+mb_IconQuestion); 
       If Parar=idNo Then 
          Begin 
               Cliente.WriteInteger(1); //Le decimos que termine 
               EnEjecucion:=False; 
               Exit 
          End 
       Else 
       If Parar=idCancel Then 
          Begin 
               Cliente.WriteInteger(1); //Le decimos que termine 
               PararEnvioRecepcion:=True; 
               EnEjecucion:=False; 
               Exit 
          End 
      End 
     Else //Para otros errores terminar 
     If Error<>0 Then 
      Begin 
           Cliente.WriteInteger(1); //Le decimos que termine 
           //Comprobamos error 
            If Error=800 Then 
               ShowMessage(' NO SE PUDO CREAR EL DIR :'#13 
                             +ExtractFilePath(Destino)); 
           EnEjecucion:=False; 
           Exit 
      End; 
     //Le decimos que continue 
     Enviando; // Retardo para simular y animación 
     Cliente.WriteInteger(0); 
     //Abrimos fichero de origen 
     SFile:=TFileStream.Create(Origen,fmShareDenyRead); 
     TamanoPaq:=Cliente.SendBufferSize Div 2; 
     GetMem(Buf,TamanoPaq); 
     // Establecemos los paquetes que vamos a enviar 
     // Número de paquetes de envío 
     NPaq:=SFile.Size Div TamanoPaq; 
     If (SFile.Size/TamanoPaq)>0.0 Then Inc(NPaq); 
     // Preparamos barra visual de evolución 
     BarraProgresoFichero.ValorMax:=SFile.Size; 
     // Le informamos para que prepare el bucle de lecturas 
     Cliente.WriteInteger(NPaq); 
     //Iniciamos Cronómetro de precisión 
     //Utilizaremos 
     //  * el cronometro 1 para el tiempo total 
     //  * el cronometro 2 para tiempos intermedios 
     //Reinicializamos el contador general 
     CronoHP1.Activa(1); 
     For x:=1 To NPaq Do 
      Begin 
           //Guardamos el tiempo al comenzar el proceso de envío del paquete 
           CronoHP1.Activa(2); 
           Leidos:=SFile.Read(Buf^,TamanoPaq); 
           ZCompress(Buf,Leidos,BufOut,Escritos,NivelCompress); 
           //Procesamos mensages 
           Application.ProcessMessages; 
           //Le respondemos si se debe cancelar en función 
           //de la variable de cancelación del proceso de recepción 
           If PararEnvioRecepcion Then 
            Begin //Debemos salir eliminando variables temporales 
                 Cliente.WriteInteger(1); //Cancelación en el server 
                 FreeMem(BufOut); 
                 FreeMem(Buf); 
                 SFile.Free; 
                 BarraProgresoFichero.ValorMax:=0; 
                 EnEjecucion:=False; 
                 Exit 
            End 
           Else Cliente.WriteInteger(0); 
           //Le enviamos información de la cantidad que debe leer 
           Cliente.WriteInteger(Escritos); 
           Retardo; // Retardo para simular y animación 
           //Le enviamos datos 
           Cliente.WriteBuffer(BufOut^,Escritos); 
           //Liberamos memoria 
           FreeMem(BufOut); 
           //Damos datos de velocidad y tiempos 
           BarraProgresoFichero.Progress:=SFile.Position; 
           Velocidad.Caption:=Format('%n KBytes/Seg', 
                                     [Leidos/(CronoHP1.Read_r(2,fcSeg)*1024)]); 
           If x>1 Then 
           Begin 
               VelocidadMedia.Caption:=Format('%n KBytes/Seg', 
                                              [SFile.Position/ 
                                                (CronoHP1.Read_r(1,fcSeg)*1024)]); 
               TiempoRestante.Caption:=DameTiempoEnHMS(Round(((SFile.Size-SFile.Position)* 
                                           CronoHP1.Read_r(1,fcSeg) 
                                          /SFile.Position))); 
               TiempoTranscurrido.Caption:=DameTiempoEnHMS(CronoHP1.Read_i(1,fcSeg)); 
           End; 
      End; 
     BarraProgresoFichero.Progress:=0; 
     //Cerramos y liberamos 
     FreeMem(Buf); 
     SFile.Free; 
     Enviando; // Retardo para simular y animación 
     //Le enviamos los aributos del fichero y la fecha de modificación 
     FHandle:=FileOpen(Origen, fmShareDenyRead); 
     Cliente.WriteInteger(FileGetAttr(Origen)); 
     Cliente.WriteInteger(FileGetDate(FHandle)); 
     FileClose(FHandle); 
     EnEjecucion:=False; 
     Except //El peor de los casos 
          EnEjecucion:=False; 
          ShowMessage('¡¡¡  ERROR GRAVE  !!!'#13'SALDREMOS DEL PROGRAMA'); 
          Self.Close; 
          Halt 
     End 
end; 

procedure TCopiaFiles.CopiaDelServer(const Origen, Destino: String); 
Var 
   Error, NPaq, TamanoPaq, TamFichero, 
   Leidos, Escritos, x, Parar : Integer; 
   FHandle : Integer; 
   SFile : TFileStream; 
   Buf, BufIn : Pointer; 
   Dir : String; 
begin 
     Try //Capturamos errores graves 
     If (Not Cliente.Connected)Or(EnEjecucion) Then Exit; 
     EnEjecucion:=True; //Prevenimos rellamadas 
     LimpiaPantalla; //Ponemos la pantalla en estado inicial 
     Enviando; // Retardo para simular y animación 
     Cliente.Writeln('COPIAFILEDESERVER'); //PIDE FICHERO DEL SERVER 
     // El fichero que buscará 
     Cliente.Writeln(Origen); 
     Recibiendo; // Retardo para simular y animación 
     // Nos tiene que retornar primero si hay error al localizar el fichero 
     Error:=Cliente.ReadInteger(); 
     // Si hubo error no procesamos en caso contrario continuamos proceso 
     If Error<>0 Then Exit; 
     //Si no hay error realizamos Comprobaciones 
     // Primero si el Dir existe 
     Dir:=ExtractFilePath(Destino); 
     If Not DirectoryExists(Dir) Then //Si no existe el dir crearlo 
       Begin 
            If Not ForceDirectories(Dir) Then 
              Begin 
                   Cliente.WriteInteger(1); //Le decimos que termine 
                   EnEjecucion:=False; 
                   Exit 
              End 
       End; 
     //Ahora si el fichero existe 
     If FileExists(Destino) Then 
        Begin 
             Parar:=0; //Inicializamos por si no es necesario 
             If Sobreescritura Then //Activamos confirmación 
                Parar:=Application.MessageBox('¿ SOBREESCRIBIR ?','ATENCIÓN', 
                                              MB_YESNOCANCEL+mb_IconQuestion); 
             If Parar=idNo Then 
                Begin 
                     Cliente.WriteInteger(1); //Le decimos que termine 
                     EnEjecucion:=False; 
                     Exit 
                End 
             Else 
             If Parar=idCancel Then 
                Begin 
                     Cliente.WriteInteger(1); //Le decimos que termine 
                     PararEnvioRecepcion:=True; 
                     EnEjecucion:=False; 
                     Exit 
                End 
        End; 
     Enviando; // Retardo para simular y animación 
     Cliente.WriteInteger(0); //Le decimos que continue 
     // Establecemos el tamaño de paquete en función del buffer 
     TamanoPaq:=Cliente.SendBufferSize Div 2; 
     //Creamos fichero de destino 
     //Ahora si el fichero existe lo borramos para evitar conflictos 
     BorraFichero(Destino); 
     //Asignamos 
     SFile:=TFileStream.Create(Destino,fmCreate); 
     //Leemos el número de paquetes que nos enviará 
     Recibiendo; // Retardo para simular y animación 
     // Recibimos el tamaño total del fichero para que pueda calcular 
     // tiempos de recepción-envío 
     TamFichero:=Cliente.ReadInteger(); 
     //Recibimos el número de paquetes comprimidos  que nos enviará 
     NPaq:=Cliente.ReadInteger(); 
     //Asignamos inicialmente la variable que contendrá los Bytes recibidos, 
     //la velocidad media de recepción de datos y el tiempo acumulado en proceso 
     //Configuramos barra visual 
     BarraProgresoFichero.ValorMax:=TamFichero; 
     //Iniciamos Cronómetro de precisión 
     //Utilizaremos 
     //  * el cronometro 1 para el tiempo total 
     //  * el cronometro 2 para tiempos intermedios 
     //Reinicializamos el contador general 
     //Reinicializamos el contador general y lo dejamos parado 
     CronoHP1.Activa(1); 
     For x:=1 To NPaq Do 
      Begin 
           //Guardamos el tiempo al comenzar el proceso de recepción del paquete 
           CronoHP1.Activa(2); 
           //Procesamos mensages 
           Application.ProcessMessages; 
           //Le respondemos si se debe cancelar en función 
           //de la variable de cancelación del proceso de recepción 
           Enviando; // Retardo para simular y animación 
           If PararEnvioRecepcion Then 
            Begin //Debemos salir eliminando variables temporales 
                 Cliente.WriteInteger(1); //Cancelación en el server 
                 SFile.Free; 
                 DeleteFile(Destino); //Borramos el fichero 
                 BarraProgresoFichero.ValorMax:=0; 
                 EnEjecucion:=False; 
                 Exit 
            End 
           Else Cliente.WriteInteger(0); 
           //Le requerimos cantidad a recibir 
           Recibiendo; // Retardo para simular y animación 
           Leidos:=Cliente.ReadInteger(); 
           //Leemos del server 
           GetMem(BufIn,Leidos); 
           Cliente.ReadBuffer(BufIn^,Leidos); 
           Retardo; //PARA PRUEBAS SIMULADAS LOCALES 
           //Descomprimimos 
           ZDecompress(BufIn,Leidos,Buf,Escritos,TamanoPaq); 
           //Escribimos en el fichero de salida 
           SFile.Write(Buf^,Escritos); 
           //Liberamos memoria 
           FreeMem(Buf); 
           FreeMem(BufIn); 
           //Damos datos de velocidad y tiempos 
           BarraProgresoFichero.Progress:=SFile.Size; 

           Velocidad.Caption:=Format('%n KBytes/Seg', 
                                     [Escritos/(CronoHP1.Read_r(2,fcSeg)*1024)]); 
           If x>1 Then 
           Begin 
               VelocidadMedia.Caption:=Format('%n KBytes/Seg', 
                                              [SFile.Size/ 
                                              (CronoHP1.Read_r(1,fcSeg)*1024)]); 
               TiempoRestante.Caption:=DameTiempoEnHMS(Round((TamFichero-SFile.Size) 
                                          *CronoHP1.Read_r(1,fcSeg) 
                                          /SFile.Size)); 
               TiempoTranscurrido.Caption:=DameTiempoEnHMS(CronoHP1.Read_i(1,fcSeg)); 
           End; 
      End; 
     //Cerramos y liberamos 
     SFile.Free; 
     Recibiendo; // Retardo para simular y animación 
     //Recibimos los aributos del fichero y la fecha de modificación 
     FHandle:=FileOpen(Destino, fmOpenWrite); 
     FileSetAttr(Destino,Cliente.ReadInteger); 
     FileSetDate(FHandle,Cliente.ReadInteger); 
     FileClose(FHandle); 
     BarraProgresoFichero.ValorMax:=0; 
     EnEjecucion:=False; 
     Except //El peor de los casos 
          EnEjecucion:=False; 
          ShowMessage('¡¡¡  ERROR GRAVE  !!!'#13'SALDREMOS DEL PROGRAMA'); 
          Self.Close; 
          Halt 
     End 
end;
EL SERVER (solo es la copia desde el cliente al server) :
Código Delphi [-]
procedure TServerForm.ServerCOPIAFILEDECLIENTECommand(ASender: TIdCommand); 
Var 
   Fichero, Dir : String; 
   Error, NPaq, Leidos, Escritos, TamanoPaq, x : Integer; 
   FHandle : Integer; 
   SFile : TFileStream; 
   BufIn, Buf : Pointer; 
begin 
     // Se esperan los siguientes parámetros 
     // Fichero (Contendrá todo el Path entero, Ejem : C:\MIDIR\FILE.XXX). 
     // Retorna si hubo error en formato integer 
     // Miraremos de comprimir los datos para darle velocidad de envío 
     // Cargamos parámetros 
     // El fichero que recibirá 
     Try 
     Fichero:=ASender.Thread.Connection.ReadLn; 
     // Realizamos Comprobaciones 
     // Primero si el Dir existe 
     Dir:=ExtractFilePath(Fichero); 
     If Not DirectoryExists(Dir) Then //Si no existe el dir crearlo 
       Begin 
            If Not ForceDirectories(Dir) Then Error:=800 //No se pudo crear Dir 
            Else Error:=0; //No hubo error 
       End 
     Else 
     If FileExists(Fichero) Then Error:=13000 //El fichero ya existe 
     Else Error:=0; 
     // Le retornamos el posible error (si existe para que decida) 
     ASender.Thread.Connection.WriteInteger(Error); 
     // Si nos retorna con error paramos proceso y si no procesamos 
     Error:=ASender.Thread.Connection.ReadInteger(); 
     //Error=0 por parte del cliente se puede continuar si no salimos 
     If Error<>0 Then Exit; 
     //No hay error por parte del cliente se puede continuar 
     BufIn:=Nil; 
     //Ahora si el fichero existe lo borramos 
     //**** Podriamos utilizar la papelera pero de momento NO 
     UtilidadFiles.BorraFichero(Fichero); 
       //De momento no hacemos nada; 
     //Creamos fichero de destino 
     SFile:=TFileStream.Create(Fichero,fmCreate); 
     // Me debe decir el tamaño de paquete que quiere MODIFICADO !!!!! 
     TamanoPaq:=ASender.Thread.Connection.RecvBufferSize Div 2; 
     //Leemos el número de paquetes de recepción 
     NPaq:=ASender.Thread.Connection.ReadInteger(); 
     For x:=1 To NPaq Do 
      Begin 
           //Verificamos si me cancela la recepción 
           If ASender.Thread.Connection.ReadInteger>0 Then 
           Begin //Se pidio cancelar, eliminamos variables 
               SFile.Free; 
               //Evitamos problemas borrando el fichero destino 
               //por estar incompleto 
               UtilidadFiles.BorraFichero(Fichero); 
               Exit 
           End; 
           //Le requerimos cantidad de bytes a recibir 
           Leidos:=ASender.Thread.Connection.ReadInteger(); 
           // Establecemos el bufer de lectura que vamos a recibir 
           GetMem(BufIn,Leidos); 
           //Leemos del cliente 
           ASender.Thread.Connection.ReadBuffer(BufIn^,Leidos); 
           //Descomprimimos 
           ZDecompress(BufIn,Leidos,Buf,Escritos,TamanoPaq); 
           //Escribimos en el fichero de salida 
           SFile.Write(Buf^,Escritos); 
           //Liberamos memoria 
           FreeMem(Buf); 
           FreeMem(BufIn); 
      End; 
     If Assigned(SFile) Then SFile.Free; //Cerramos y liberamos 
     //Recibimos los aributos del fichero y la fecha de modificación 
     FHandle:=FileOpen(Fichero, fmOpenWrite); 
     SetFileAttributes(PChar(Fichero),ASender.Thread.Connection.ReadInteger); 
     FileSetDate(FHandle,ASender.Thread.Connection.ReadInteger); 
     FileClose(FHandle); 
     Except //Por si se desmadra el tema capturamos excepciones 
     If Assigned(SFile) Then SFile.Free; //Cerramos y liberamos 
     End 
end;
Como verás cada conexión tiene su propio buffer pero que lo que importa es como se gestiona.

Ya sé que hay parámetros que no entenderás o que no están documentados pero pertenecen a mi programa y son muy extensos de explicar y de documentar....

Espero que te sea ilustrativo lo anteriormente mencionado.

No soy programador. Solo ingeniero. Por lo que esto para mí es una aficción útil pero nada mas.

Saludos a todos.
__________________
www.sintecsl.es

Última edición por nlsgarcia fecha: 15-07-2015 a las 23:24:28. Razón: Sintaxis Delphi
Responder Con Cita
  #10  
Antiguo 20-07-2010
Avatar de Faust
Faust Faust is offline
Miembro
 
Registrado: abr 2006
Ubicación: México D.F.
Posts: 930
Poder: 19
Faust Va por buen camino
En efecto, muy ilustrativo y muy útil ...

Te tomas muy en serio tu hobby, pues se nota que eres muy bueno...

Estoy programando utilizando tus ejemplosy adecuándolos a mis necesidades.

Muchas gracias amigo y date una vuelta por otras secciones del foro donde serás bienvenido
__________________
Herr Heins Faust
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
TcpClient, TCPServer e Hilos Joacko Internet 3 27-09-2010 19:04:56
TcpClient y TcpServer Caro OOP 2 01-10-2008 19:32:34
Glyphs para Botones, sirven los ICO para esto ? mtpedro Gráficos 8 01-02-2006 09:54:59
tcpserver y tcpclient ajgesino Internet 2 23-01-2005 19:16:35
Manejo de TCPClient y TcpServer de las indy? Pally Internet 1 04-08-2003 15:11:08


La franja horaria es GMT +2. Ahora son las 22:43:06.


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