Cliente / Servidor TCP con Indy II

Bueno pues aquí tienen la segunda parte del post anterior sobre el establecimiento de una comunicación Cliente / Servidor con Indy.

Lo que voy a postear a continuación es la parte correspondiente al Server.



En la parte Type, se define el siguiente puntero que almacena la información de los clientes y que se liberará cuando se desconecten.



type
PConexao = ^TConexao;
TConexao = record
IP: ShortString;
ThreadID: Cardinal;
Connection: TidTCPServerConnection;
Usuario: ShortString;
end;





En el evento OnCreate :





procedure TForm1.FormCreate(Sender: TObject);

begin

  IdTCPServer1.Active := true;

  cmd:= TStringList.Create; //Almacena los comandos de los clientes

  conn:= TList.Create; //Listado que contiene los usuarios clientes que están conectados al Server

end;




Evento OnClose :





procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

begin

  tag:= conn.Count; //Cuenta el número de clientes conectados

  if tag > 0 then

  begin

    action:= caNone;

    Application.MessageBox('No se puede cerrar el Server ya que hay clientes      conectados','Informacion',mb_iconInformation)

  end

  else

  begin

    cmd.Free;

    Conn.Free;

    IdTCPServer1.Active := false;

  end;

end;




Procedimientos asociados al componente IdTCPServer :



Al conectar:





Procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);

var ConAux: PConexao;

begin

 cmd.text:= AThread.Connection.ReadLn;

 if AnsiSameText(Admin,cmd.Values['nick']) then

    AThread.Connection.Writeln('nick existent o es el nick del Administrador.')

 else

 begin

   xUniqueUser := UniqueUser(cmd.Values['nick']);

   if xUniqueUser then

   begin

     AThread.Connection.Writeln('Bienvenido al Servidor'#10);

     GetMem(ConAux,SizeOf(TConexao));

     try

       ConAux.ThreadID := AThread.ThreadID;

       ConAux.Connection:= AThread.Connection;

       ConAux.IP := AThread.Connection.Socket.Binding.PeerIP;

       ConAux.Usuario := cmd.Values['nick'];



       AThread.Data := TObject(ConAux);

       conn.Add(ConAux);

       UsuarioEntrou;

     finally

       //FreeMem(ConAux);

       ShowConnections;

     end;

   end

   else AThread.Connection.Writeln('Nick existente');

 end;

end;






Al Desconectar:





procedure TForm1.IdTCPServer1Disconnect(AThread: TIdPeerThread);

var

  ConAux: PConexao;

  aux: string;

begin

  if xUniqueUser then

  begin

    ConAux:= PConexao(AThread.Data);

    try

      conn.Remove(ConAux);

      aux:= ConAux.Usuario + ' ha salido de la sala de chat.';

      memo1.lines.add(aux);

      SendMsgToAll(aux);

      AThread.Data := nil;

    finally

      FreeMem(ConAux); //libera el puntero de la información del cliente

    end;

    ListUsers;

    ShowConnections;

  end

  else xUniqueUser:= true;

end;




On Execute :





procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);

begin

  try

    cmd.Text:= AThread.Connection.ReadLn;

    if VerificaComando(cmd.text,'msg=',true) then

    begin

       SendMsg;

       memo1.lines.add(ReceiveMsg(cmd.text));

    end;

  except

    on e: Exception do

    begin

      AThread.Connection.WriteLn('server_error='+e.message);

    end;

  end;

end;




Probado para Indy 9 (delphi 7)

Si quiere utilizar Indy10  (delphi 2009 o superior) hay que cambiar:

- AThread : TIdPeerThread    por    AContext: TIdContext

- AThread     por    AContext

- AThread.connection.readln     por   AContext.Connection.iohandler.ReadLn;

- AThread.connection.writeln (XXX)   por AContext.Connection.iohandler.Writeln (XXX);



En el record:



  TConexao = record

    IP: ShortString;

    ThreadID: Cardinal;

    Connection: TidTCPConnection;   <----hay a="" adiendo="" cambiar="" el="" en="" esto="" idtcpconnection="" nbsp="" p="" que="" uses="">    Usuario: ShortString;

  end;







enlace | Codigo fuente





Autor: Manoel Campos da Silva Filho

           Professor da Escola Técnica Federal de Palmas

           E-Mail: mcampos@etfto.gov.br













2 comentarios:

  1. hola
    no lo he podido ejecutar con indy 10 en delphi xe7, me podria ayudar por favor?

    ResponderEliminar
  2. Ya lo corregi, lo tengo para delphi xe7 Funcionando

    ResponderEliminar

Simulación del movimiento de los electrones en un campo electrico

Espectacular simulación realizada con OpenGL del movimiento de los electrones cuando atraviesan un campo eléctrico. Como muestra la image...