Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Coloboración Paypal con ClubDelphi

Ver Resultados de Encuesta: Crear componentes exclusivos miembros Premium
18 90,00%
No 2 10,00%
Votantes: 20. Tú no puedes votar en esta encuesta

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 29-09-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 26
seoane Va por buen camino
Cita:
Empezado por Julián Ver Mensaje
Por otra parte seoane tenia un código por ahí para enviar archivos vía tcp usando threads, que es lo que le vendría de perlas a estos componentes. Ademas de una limpieza de su chapucero código, jeje.
Ese código que mencionas lo puse solo como un ejemplo de como usar los componentes que traía el Turbo delphi explorer, y la verdad es que es un poco chapuza. Tiene mucho que mejorar, sobre todo la interacción con el usuario (cancelar, parar, reanudar, informar de errores, etc ...)

Lo malo es que vengo de pelearme, por culpa de un trabajito que me surgió, con un programa de intercambio de ficheros bastante complejo y ahora mismo estoy bastante cansado del tema

Aunque si al final me decido a hacer algo habría que decidir primero que librerías se usarían. ¿Winsock a pelo? ¿Indy? ¿Synapse? o alguna otra librería compatible con freepascal y linux. La elección es importante, ya que se convertirá en un requisito de instalación en los futuros componentes.
Responder Con Cita
  #2  
Antiguo 29-09-2007
Avatar de jhonny
jhonny jhonny is offline
Jhonny Suárez
 
Registrado: may 2003
Ubicación: Colombia
Posts: 7.070
Poder: 32
jhonny Va camino a la famajhonny Va camino a la fama
Cita:
Empezado por Julián
El caso es que para el chat de dicho programa uso dos com
ponentes: el TicsChatServer y el TicsChatClient , que no encontrareis en ninguna parte porque los he hecho yo y nadie mas los tiene, (excepto jhonny).

Son muy faciles de usar, pero aún asi tengo hech una demo sencilllita, que hice para jhonny cuando se los pase.
Los tenia, por que cuando me los pasaste estaba trabajando en otra empresa diferente, en la cual tuve que formatear esa maquina rapidamente, (Bueno, no me quedo tiempo de nada , las razones de ese formateo rapido me las reservo , solo cumplia ordenes). Dias despues tuve que irme de allí para no volver, despues de eso tuve una de mis largas desaparecidas del Club y no tuve la oportunidad de entrar de nuevo al AjedrezChat, incluso hoy por hoy, tengo restringido el acceso por dicho puerto , ni con el putty he podido entender como saltarme esa restriccion , es una larga historia, quizas algun dia la contare.
__________________
Lecciones de mi Madre. Tema: modificación del comportamiento, "Pará de actuar como tu padre!"

http://www.purodelphi.com/
http://www.nosolodelphi.com/

Última edición por jhonny fecha: 29-09-2007 a las 20:17:51. Razón: Agregar el quizas
Responder Con Cita
  #3  
Antiguo 29-09-2007
Avatar de Julián
Julián Julián is offline
Merodeador
 
Registrado: may 2003
Ubicación: en mi casa
Posts: 2.029
Poder: 10
Julián Va por buen camino
Cita:
Empezado por seoane Ver Mensaje
Ese código que mencionas lo puse solo como un ejemplo de como usar los componentes que traía el Turbo delphi explorer, y la verdad es que es un poco chapuza.
Oño!, a ver si no me explique bien: El código chapucero al que me referia es el mío, no el tuyo. Que el tuyo no lo miré nada mas que de pasada, y por cierto, de chapuza nada. Otra cosa es que le falte algo.

Un saludo aclaratorio
__________________
"la única iglesia que ilumina es la que arde"
Anonimo
Responder Con Cita
  #4  
Antiguo 29-09-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 26
seoane Va por buen camino
Bueno julian, y que características piensas que puedan tener esos componentes ???. Yo me imagino uno que haga de servidor, y que tenga un solo método "listen" que dispare un thread que se ponga a la escucha en un puerto para realizar la transferencia, el método listen devuelve el puerto por el que esta escuchando. El cliente por su parte tendrá solo método "send" que envío un fichero a un puerto especifico.

Por ejemplo para realizar una transferencia, el que actúe como servidor ejecutara el método listen y el numero de puerto que le devuelva se lo pasa al cliente, el cliente por su parte usara el método send. Lo que falta es saber como mandara el servidor la información del puerto al cliente, pues si se supone que es un accesorio de un chat, ya debe de existir una conexión entre los dos, así que se puede utilizar esa.

Me da la sensación de que no me he explicado muy bien
Responder Con Cita
  #5  
Antiguo 29-09-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.142
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

A ver, ponersus de acuerdo.

PD. Pero está bien, está bien.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #6  
Antiguo 30-09-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 26
seoane Va por buen camino
Vamos a ver Julian, un primer esbozo podría ser esto:
Código Delphi [-]
unit transfer;

interface

uses Windows, Sysutils, Classes, Winsock;

type
  EBindError = class(Exception);
  EConnectError = class(Exception);
  EWinsockError = class(Exception);

  TFileReceiver = class(TThread)
  private
    FFile: TFileStream;
    FReceived: int64;
    FServer: TSocket;
    FSocket: TSocket;
    FToken: int64;
    procedure Receive;
    function WaitForData(Count: Integer): Boolean;
  protected
    procedure Execute; override;
  public
    constructor Create(Filename: String; Port: Integer; Token: int64);
    destructor Destroy; override;
    property Received: int64 read FReceived;
  end;

  TFileSender = class(TThread)
  private
    FFile: TFileStream;
    FSended: int64;
    FSocket: TSocket;
    FToken: int64;
  protected
    procedure Execute; override;
  public
    constructor Create(Filename: String; Host: String; Port: Integer;
      Token: int64);
    destructor Destroy; override;
    property Sended: int64 read FSended;
  end;

implementation

const
  BUFFER_SIZE = 32 * 1024;

{ TFileReceiver }

constructor TFileReceiver.Create(Filename: String; Port: Integer; Token: int64);
var
  Addr: TSockAddr;
begin
  FFile:= nil;
  FReceived:= 0;
  FServer:= INVALID_SOCKET;
  FSocket:= INVALID_SOCKET;
  FToken:= Token;
  FFile:= TFileStream.Create(Filename,fmCreate or fmShareDenyWrite);
  FServer:= Socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
  if FServer = INVALID_SOCKET then
    raise EWinsockError.Create('Socket');
  Addr.sin_family:= AF_INET;
  Addr.sin_port := htons(Port);
  Addr.sin_addr.s_addr := htonl(INADDR_ANY);
  if Bind(FServer, Addr, sizeof(Addr)) = SOCKET_ERROR then
    raise EWinsockError.Create('Bind');
  if Listen(FServer, 1) = SOCKET_ERROR then
    raise EWinsockError.Create('Listen');
  FreeOnTerminate:= TRUE;
  inherited Create(TRUE);
end;

destructor TFileReceiver.Destroy;
begin
  if FSocket <> INVALID_SOCKET  then
    CloseSocket(FSocket);
  if FServer <> INVALID_SOCKET  then
    CloseSocket(FServer);
  FFile.Free;
  inherited;
end;

procedure TFileReceiver.Execute;
var
  Addr: TSockaddr;
  Size: Integer;
  FDSet: TFDSet;
  TimeVal: TTimeVal;
begin
  while not Terminated do
  begin
    TimeVal.tv_sec:= 0;
    TimeVal.tv_usec:= 10000;
    FD_ZERO(FDSet);
    FD_SET(FServer, FDSet);
    if Select(0, @FDSet, nil, nil, @TimeVal) > 0 then
    begin
      Size:= Sizeof(Addr);
      FSocket:= Accept(FServer, @Addr, @Size);
      if FSocket <> INVALID_SOCKET then
      begin
        Receive;
        break;
      end;
    end;
  end;
end;

procedure TFileReceiver.Receive;
var
  i: Integer;
  Buffer: PChar;
  Token: int64;
begin
  if WaitForData(Sizeof(Token)) then
    if Recv(FSocket, Token, Sizeof(Token), 0) = Sizeof(Token) then
      if Token = FToken then
      begin
        GetMem(Buffer,BUFFER_SIZE);
        try
          while WaitForData(1) do
          begin
            i:= Recv(FSocket, Buffer^, BUFFER_SIZE, 0);
            if i > 0 then
            begin
              FFile.WriteBuffer(Buffer^,i);
              inc(FReceived, i);
            end else
              break;
          end;
        finally
          FreeMem(Buffer);
        end;
      end;
end;

function TFileReceiver.WaitForData(Count: Integer): Boolean;
var
  i: Integer;
  Buffer: PChar;
  FDSet: TFDSet;
  TimeVal: TTimeVal;
begin
  Result:= FALSE;
  GetMem(Buffer,Count);
  try
    while not Terminated do
    begin
      TimeVal.tv_sec:= 0;
      TimeVal.tv_usec:= 10000;
      FD_ZERO(FDSet);
      FD_SET(FSocket, FDSet);
      if Select(0, @FDSet, nil, nil, @TimeVal) > 0 then
      begin
        i:= Recv(FSocket, Buffer^, Count, MSG_PEEK);
        if i > 0 then
        begin
          if i = Count then           
          begin
            Result:= TRUE;
            break;
          end else
            Sleep(10);
        end else
          break;
      end;
    end;
  finally
    FreeMem(Buffer);
  end;
end;

{ TFileSender }

constructor TFileSender.Create(Filename, Host: String; Port: Integer;
  Token: int64);
var
  Address: u_long;
  HostEnt: phostent;
  Addr: sockaddr_in;
begin
  FFile:= nil;
  FSended:= 0;
  FSocket:= INVALID_SOCKET;
  FToken:= Token;
  FFile:= TFileStream.Create(Filename,fmOpenRead or fmShareDenyWrite);
  Address:= inet_addr(Pchar(Host));
  if Address = INADDR_NONE then
  begin
    HostEnt:= gethostbyname(PChar(Host));
    if HostEnt <> nil then
      Address:= PInAddr(HostEnt.h_addr_list^)^.S_addr;
  end;
  if Address <> INADDR_NONE then
  begin
    FSocket:= Socket(AF_INET, SOCK_STREAM, 0);
    if FSocket = INVALID_SOCKET then
      raise EWinsockError.Create('Socket');
    Addr.sin_family:= AF_INET;
    Addr.sin_addr.S_addr:= Address;
    Addr.sin_port:= htons(Port);
    if Winsock.Connect(FSocket, Addr, Sizeof(Addr)) = SOCKET_ERROR then
      raise EConnectError.Create('Connect');
  end else
    raise EConnectError.Create('Connect');
  FreeOnTerminate:= TRUE;
  inherited Create(TRUE);
end;

destructor TFileSender.Destroy;
begin
  if FSocket <> INVALID_SOCKET  then
    CloseSocket(FSocket);
  FFile.Free;
  inherited;
end;

procedure TFileSender.Execute;
var
  i,j: Integer;
  Buffer: PChar;
begin
  if Send(FSocket,FToken,Sizeof(FToken),0) = Sizeof(FToken) then
  begin
    GetMem(Buffer,BUFFER_SIZE);
    try
      i:= FFile.Read(Buffer^,BUFFER_SIZE);
      while (i > 0) and not Terminated do
      begin
        j:= Send(FSocket,Buffer^,i,0);
        if i > 0 then
        begin
          inc(FSended,j);
          if j <> i then
            FFile.Seek(j-i,soCurrent)
        end else
          break;
        i:= FFile.Read(Buffer^,BUFFER_SIZE);
      end;
    finally
      FreeMem(Buffer);
    end;
  end;
end;

var
  WSAData: TWSAData;

procedure Startup;
begin
  if WSAStartup(MAKEWORD(1, 1), WSAData) <> 0 then
    raise EWinsockError.Create('WSAStartup');
end;

procedure Cleanup;
begin
  if WSACleanup <> 0 then
    raise EWinsockError.Create('WSACleanup');
end;

initialization
  Startup;

finalization
  Cleanup;

end.
Son dos clases descendientes de la clase TThread. Solo utilizo funciones del Winsock, nada de librerias.

Y un ejemplo de como usarla seria el siguiente:
- Uno de los usuarios del chat decide mandar un archivo a otro, así que le manda un mensaje pidiéndole permiso.
- El otro crea una instancia del TFileReceive y le devuelve un mensaje con el numero de puerto y un código de seguridad (token)
- Ahora el primero crea una instancia del TFileSender, usando el puerto y el token que acaba de recibir, y envía el archivo.

Esto llevado a código:
Código Delphi [-]
// Para crear el receptor
with TFileReceiver.Create('c:\borrame.exe',61985,789) do
  begin
    Resume;
  end;

// Para crear el emisor
begin
 with TFileSender.Create(ParamStr(0),'127.0.0.1',61985,789) do
  begin
    Resume;
  end;
end;
El receptor y el emisor solo se tienen que poner de acuerdo en el puerto y el token, si el emisor y el receptor ya mantienen una conexión de chat no sera difícil implementar un protocolo para hacer eso.

Bueno, son las 3 AM y esto es todo lo que se me ocurre

Espero que se me entienda.

Última edición por seoane fecha: 30-09-2007 a las 03:27:12.
Responder Con Cita
  #7  
Antiguo 02-10-2007
Avatar de Julián
Julián Julián is offline
Merodeador
 
Registrado: may 2003
Ubicación: en mi casa
Posts: 2.029
Poder: 10
Julián Va por buen camino
Jau!

tengo muy poco tiempo estos días, mas que poco ninguno,por eso no he podido poner esto antes:

icsChatComponents

Ahí van los componentes para tener un servidor y cliete chat, con el código fuente y una demo.
Mi consejo es que, a quien le interese el tema, pruebe la demo antes que nada. Y despues que se ponga a mirar el código chapucerillo, jeje.

Para probar la demo no hay mas que ejecutarla, y activar el servidor, y despues si activa el cliente se conecta al server. Despues puede ejecutar otra instancia del programa y conectarse al mismo server ( Con otro Nick para que no de error, claro!!)

Gueno, ya me direis, un saludo!

Lo olvidava: para instalar los componentres se necesitan los ICS de Fpiette.
__________________
"la única iglesia que ilumina es la que arde"
Anonimo

Última edición por Julián fecha: 02-10-2007 a las 17:54:59.
Responder Con Cita
  #8  
Antiguo 03-10-2007
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.142
Poder: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Está muy bien Julián. La "demo" por lo menos funciona estupendamente.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

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
¿RSS del Club Delphi? K-ba La Taberna 5 30-07-2007 22:17:40


La franja horaria es GMT +2. Ahora son las 12:19:50.


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