Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

etspaz

função para localizar cliente conectado

Recommended Posts

oi,

seguindo algumas dicas eu to conseguindo fazer um gerenciador de conexões,eu peguei esta função que será usada para saber a posição do cliente conectado e adaptei oa meu prog.

Function TForm1.LocalizaCliente(Cli : Pointer):Integer; 
Begin 
Result := IDConexoes.IndexOf(Cli); 
End;

porém, acho que fiz algo errado, pois dá estes erros:

 

[Error] unit_sig.pas(45): Undeclared identifier: 'LocalizaCliente'

[Error] unit_sig.pas(45): ';' expected but '(' found

[Error] unit_sig.pas(47): Undeclared identifier: 'Result'

[Error] unit_sig.pas(47): Missing operator or semicolon

[Error] unit_sig.pas(84): Undeclared identifier: 'LocalizaCliente'

[Fatal Error] proje_siglan.dpr(6): Could not compile used unit 'unit_sig.pas'

 

para criar a função eu tenho que declarar algo antes?

do jeito que estava eu só alterei os nomes.

 

esta função será usada no evento onclientread de um server socket.

vejam:

 

Var Msg : String;
IDCli : integer;
HoraStr : String;
begin
Msg := socket.ReceiveText;
If Msg = 'HORA?' then
  Begin
  IDCli := LocalizaCliente(Socket.Data);
  HoraStr := FormatDateTime('HH:mm:ss',Now);

If (IDCli >= 0) then
  Servidor.Socket.Connections[IDCli].SendText(HoraStr);
end;
end;

percebi que a função não é identificada.

o que está errado?

 

desde já agradeço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

eu mudei um pouco para continuar estudando, mas agora quando quando tenho varias conexoes simultaneas e envio varias mensagens da este erro:

LIST INDEX OUT OF BOUNDS (2)

 

vou colocar todo codigo pra ficar mais claro.

public
	{ Public declarations }
	IDConexoes : TList;
	conexoes: TList;
	tempo: TTime;

  end;

var
  Form1: TForm1;

implementation


uses Unit_login;


{$R *.dfm}

//Function TForm1.LocalizaCliente(Cli : Pointer):Integer;
//Begin
//Result := IDConexoes.IndexOf(Cli);
//End;



procedure TForm1.Timer1Timer(Sender: TObject);
begin
  //if (Tempo >= STrToTime('00:00:00')) then
  //begin
   // Label1.caption := TimeToStr(Tempo - StrToTime('00:00:01'));
	//Tempo:= Tempo - StrToTime('00:00:01');
 // end
  //else
 // begin
  //Timer1.Enabled:=false;
 // ShowMessage('ee');
 // end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
//Tempo := StrToTime('00:00:20');
Servidor.Active := True;
//IDConexoes := TList.Create;
//IDConexoes.Clear;
conexoes:= TList.Create;

end;

procedure TForm1.servidorClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
// este é o primeiro jeito !!!
 // Var Msg : String;
//IDCli : integer;
//HoraStr : String;
//begin
//Msg := socket.ReceiveText;
//If Msg = 'HORA?' then
 //Begin
  //IDCli := LocalizaCliente(Socket.Data);
 // HoraStr := FormatDateTime('HH:mm:ss',Now);

//If (IDCli >= 0) then
 // Servidor.Socket.Connections[IDCli].SendText(HoraStr);
//end;




// este é o segundo jeuto!!!!
 //  Var MsgRecebida : String;
//I : integer;/
//begin
 // MsgRecebida := socket.ReceiveText;  // Pega o conteúdo enviado

//  For i := 0 to servidor.Socket.ActiveConnections-1 do
  //   Servidor.Socket.Connections[i].SendText(MsgRecebida);

//end;


//este é o terceiro jeito !!!
var msg : string;
	  NumConex : integer;
begin
NumConex := Conexoes.IndexOf(Socket.Data);

if NumConex >= 0 then
  Begin
	 msg := socket.ReceiveText; // pego a menssagem q chegou
	 msg := AnsiLowerCase(msg); // transformo todas as letras para minuscula
	 servidor.Socket.Connections[NumConex].SendText(msg);  //envio d volta pra
   //														   //  quem enviou	
  end;
end;







procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//IDConexoes.Free; 
end;

procedure TForm1.servidorClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
  Var IDsocket : ^String; // Variavel utilizada par identificar o sockets
begin
 New(IDSocket);
 Socket.Data := IDSocket;
 Conexoes.Add(Socket.data);
end;

//Var
//IDsocket : ^byte;
//begin
 //New(IDSocket);
 //Socket.Data := IDSocket;
 //IDConexoes.Add(Socket.data);
//end;
 

procedure TForm1.servidorClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
//Var
// NumConex : integer;
Begin
//IDConexoes.Remove(Socket.Data);
//Dispose(Socket.Data);
end;


procedure TForm1.FormDestroy(Sender: TObject);
begin
conexoes.Destroy;
end;

end

onde está comentado são os exemplos que eu testei primeiro, o que está como primeiro jeito foi o que deu problema na função que citei no post.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tente rodar passo a passo para conseguir pegar o erro na linha que acontece... normalmente este erro é de um stringlist ou componente do tipo que você pede uma determinada posição, mas o mesmo não existe.

Compartilhar este post


Link para o post
Compartilhar em outros sites

e ae marcio beleza,

eu fiz o que tu disse e percebi que o problema não é a quantidade de conexões ou de mensagens e sim quando tem mais de um conectado enviando mensagens, o servidor responde normal, mas quando um se desconecta da este erro, ou seja, o servidor não está alterando a posição do indice na lista dos conectados e um envia mensagem ele tenta responder, mas manda para o que não exixte mais , deu pra entender?

 

aqui ele pega a posição do cliente conctado

NumConex := Conexoes.IndexOf(Socket.Data);

 

e aqui ele tenta responder, mas quando um cliente sai da o erro,porque não tá atualizando a lista quando este sai.

 

msg := socket.ReceiveText; // pego a menssagem q chegou

msg := AnsiLowerCase(msg); // transformo todas as letras para minuscula

servidor.Socket.Connections[NumConex].SendText(msg); //envio d volta pra quem enviou

 

como eu faço pra ele atualizar a lista na hora que alguem sair?

 

cara tenho que aproveitar e agradecer a todos membros e moderas do IMASTER, pois com vcs eu evolui muito e faço questão de dizer que graças a vcs consegui um novo estágio, muito melhor que o atual, em varios pontos:

vou começar em janeiro e ja tem um projeto pra eu trabalhar, também finaceiramente ....

ja que o atual paga pouco e não exige muito de mim, mas sou grato a eles por me deixarem livre pra praticar sempre por conta e pesquisar, assim encontrei vcs, porque se dependesse da facu eu estaria no maximo num telemarketing, hehe.

no teste pratico eu apliquei varias coisas que aprendi com vcs, fazendo mais do que eles pediram e isto foi o diferencial.

meus sinceros agradecimentos e parabéns a todos que participam deste forum http://forum.imasters.com.br/public/style_emoticons/default/worshippy.gif

 

eu desejo sempre poder colaborar quando estiver ao meu alcance, vlw!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entendi sim...

Acho que você não teria como atualizar a lista, e sim o próprio socket faz isto se a conexão tiver enviado o pedido de desconexão, assim o servidor sabe que o client saiu e remove ele, mas se caso não ocorra esta solicitação, para o servidor é como se o client ainda estivesse ativo, o que poderia fazer é usar um try except neste bloco de código...

Opa, coisa boa, é sempre bom conseguirmos novos desafios, espero que se realize profissionalmente, qualquer coisa pode contar conosco aqui do fórum http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde etspaz, dá uma olhada nesta função que retorna o número dos ip's da rede

 

unit Unit1;

 

interface

 

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, IdBaseComponent, IdComponent, IdRawBase, IdRawClient,

IdIcmpClient, StdCtrls;

 

type

TForm1 = class(TForm)

Memo1: TMemo;

Button1: TButton;

IdIcmpClient1: TIdIcmpClient;

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

 

var

Form1: TForm1;

 

implementation

 

{$R *.dfm}

 

procedure TForm1.Button1Click(Sender: TObject);

const

IP: string = '10.1.1.';

var

i: integer;

begin

 

Memo1.Clear;

 

for i := 1 to 99 do

begin

 

IdIcmpClient1.Host := IP+IntToStr(i);

IdIcmpClient1.TTL := 50;

IdIcmpClient1.ReceiveTimeout := 50;

 

IdIcmpClient1.Ping;

 

if IdIcmpClient1.ReplyStatus.ReplyStatusType = rsEcho then

 

Memo1.Lines.Add(IdIcmpClient1.ReplyStatus.FromIpAddress);

 

end;

 

 

end;

 

end.

 

Agora para mostrar o nome ainda não descobri, quando você encontrar, posta aqui para a gente poder estudar, hehe, falow!!!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara, encontrei um tópico onde tem um aplicativo para download, postado pelo nosso colega marcio.theis um ano atrás, que é bem interessante, demora um pouco para carregar, mas testei aqui no delphi 7 e funcionou beleza,

http://forum.imasters.com.br/index.php?showtopic=207695

Valeu!!

Compartilhar este post


Link para o post
Compartilhar em outros sites

opa, PAZ E AMOR A TODOS,

desculpem a demora, mas não tenho net em casa, só no trampo, hehe.

bem, o problema da desconexão eu resolvi, era simples.

como o marcio disse tem que informar que houve a desconexão, então , no evento clientDisconnect, cloquei:

Conexoes.Remove(Socket.Data);
Dispose(Socket.Data);

que ele atualiza a lista, eu só tava dando um destroy, quando alguém se desconectava.

 

pra exibir a quantidade de clientesconectados eu coloquei um timer, criei a variavel do tipo int e fiz assim no ontimer:

qte_conexoes:=Servidor.Socket.ActiveConnections;
Edit2.Text:=IntToStr(qte_conexoes);

e visualisar a posição de quem receberá uma resposta eu coloquei no onclientread:

Label3.Caption:=IntToStr(NumConex);

 

agora to analisando os exemplos do Marcio que o João Paulo indicou pra pegar o ip e nome, porque no exemplo acima só exibe a quantidade total de clientes conectados e a posição atual de um , mas o mesmo pode cair e voltar, aí sua posição será outra e o sistema funcionará, mas o operador não saberá qual maquina é exatamente.

vlw.

Compartilhar este post


Link para o post
Compartilhar em outros sites

ola,

pra pegar o hostname e ip usei umas propriedades do socket:

i:= Socket.RemoteAddress;

x:= Socket.RemoteHost;

onde i e x são do tipo string, daí posso fazer o que for necessario, tipo num cadastro de historico....

 

bem já consegui controlar quem conecta, se desconecta, fazer o servidor enviar mensagens para todos ou um cliente especifico

Porém, por enquanto, tenho duas duvidas.

1-Não to sabendo como fazer pra fazer o servidor receber uma mensagem de um cliente e ja enviar pra outro cliente.

tipo, a fala com b, através do servidor, tenho que criar uma lista dos conectados como no servidor?

porque no servidor tenho um combobox, aí seleciono o cliente e envio, mas no cliente mesmo tendo um combobox terei que enviar para o servidor.

 

2-fiz um teste pra o servidor desligar o monitor, assim:

 

ReceivedCmd := Socket.ReceiveText;

 

//Desligar Monitor

if ReceivedCmd = '1' then

begin

//Comando...

SendMessage (Application.Handle, WM_SYSCOMMAND, SC_MONITORPOWER, 1);

end;

//Liga Monitor

if ReceivedCmd = '2' then

begin

//Comando...

SendMessage (Application.Handle, WM_SYSCOMMAND, SC_MONITORPOWER, -1);

end;

 

neste caso, se a mensagem que o cliente enviar for 1 ele ele desliga o monitor, quando o cliente está na mesma maquina que o servidor, funciona, mas quando está em outra não acontece nada, só exibe a mensagem no caso 1.

 

ah, e alguém sabe onde posso pesquisar sobre estes comandos pra executar, tipo desligar pc, alterar alguma configuração do windows etc...?

um abraço

Compartilhar este post


Link para o post
Compartilhar em outros sites

bom dia a todos!

eu coloquei um combobox no cliente para que quando ele se conectar ao serv. seja visualizado no combo os clientes conectados para este poder enviar menasgens a qualquer outro cliente, mas não to conseguindo fazer ele receber esta lista.

se alguém souber como faço pro nservidor atualizar o combo dos clientes, com os outros clientes conectados e quando um se desconectyar , pode me dar uma ajuda por favor?

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.