etspaz 0 Denunciar post Postado Dezembro 20, 2007 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
etspaz 0 Denunciar post Postado Dezembro 20, 2007 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
marcio.theis 3 Denunciar post Postado Dezembro 21, 2007 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
etspaz 0 Denunciar post Postado Dezembro 21, 2007 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
marcio.theis 3 Denunciar post Postado Dezembro 21, 2007 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
João Paulo Taraciuk 0 Denunciar post Postado Dezembro 21, 2007 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
João Paulo Taraciuk 0 Denunciar post Postado Dezembro 21, 2007 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
etspaz 0 Denunciar post Postado Dezembro 26, 2007 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
etspaz 0 Denunciar post Postado Dezembro 28, 2007 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
etspaz 0 Denunciar post Postado Janeiro 2, 2008 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