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


Relacionados:

Cliente / Servidor TCP con Indy I

Cliente / Servidor UDP

Código fuente de un proxy con Synapse

Obtener el NS, MX, SOA de un dominio con Indy



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