idTcpClient pode ficar escutando os comandos do idTcpServer?
20/03/2006
0
O cliente faz uma pergunta o servidor responde, o servidor faz uma pergunta o cliente responde e assim por diante. Se o cliente fizer mais de uma pergunta por vez o servidor enviará uma reposta de cada vez até por que será feita uma resposta por vez:
IdTcpClient.WriteLn(‘#Comando’); ShowMessage(idTcpClient.ReadLn());
Minha dúvida é a seguinte: Se eu quiser enviar um comando do cliente para o servidor basta colocar um botão e fazer:
idClient.WriteLn(‘HORA’); //um exemplo para pedir a hora do servidor MsgResposta := idClient.ReadLn();//Aqui já pego a resposta do servidor, certo?
:arrow: :arrow: No servidor coloco no evento OnTcpServerExecute;
Var Msg : String; Begin Msg := UpperCase(idTcpServer.ReanLn()); If Msg = ‘#HORA’ then // se o cliente estiver pedindo a hora envio para ele uma resposta... idTcpServer.WriteLn(Time); …
Resumindo, sabemos que para ler as solicitações do cliente basta colocar uma instrução neste evento no servidor, certo? Mais e no cliente, como faço para aguardar os comandos do servidor. Tentei colocar um timer para ficar assim: :idea: :idea: :idea:
var msg : String; begin msg := ´´; if IdTCPClient.Connected then begin msg := IdTCPClient.ReadLn(); if msg <>´´ then begin ListBox1.Items.Add(msg); end else begin Exit; end; end; end;
Minha pergunta é tem como o cliente ficar escutando os comandos do servidor, sem ser nas seqüências abaixo?
IdTcpClient.WriteLn(‘#Comando’); ShowMessage(idTcpClient.ReadLn());
:?: :?: :?:
Paullsoftware
Posts
21/03/2006
Massuda
21/03/2006
Paullsoftware
eu imaginei isso também, por exemplo eu pensei em pedir dos clientes com o comando [b:1c03103f21]#HORA[/b:1c03103f21] por exemplo, mais ai pensei: ele vai pedir a hora de todos e depois que o último receber o pedido é que ele vai processar a do primeiro, estou certo?
21/03/2006
Massuda
// código no servidor var List: TList; Peer: TIdPeerThread; ... List := IdTCPServer1.Threads.LockList; try for I := 0 to List.Count - 1 do begin // List[I] é uma das threads do servidor Peer := TIdPeerThread(List[I]); Peer.Connection.WriteLn(´DESLIGAR´); if Peer.Connection.ReadLn(10, 100) <> ´OK´ then begin // loga/avisa que não respondeu end; end; finally IdTCPServer1.Threads.UnlockList; end; // código no cliente ... Comando := IdTCPClient1.ReadLn; if Comando = ´DESLIGAR´ then begin IdTCPClient1.WriteLn(´OK´); //prepara para desligar end ...
21/03/2006
Paullsoftware
procedure TfMain.SendAll(wTipo:String); var List : TList; Peer : TIdPeerThread; I : Integer; begin List := TCPServer.Threads.LockList; try for I := 0 to List.Count -1 do begin Peer := TIdPeerThread(List[i]); if wTipo = UpperCase(´:1´) then begin Peer.Connection.WriteLn(´TELA´) end else if wTipo = UpperCase(´:2´) then begin Peer.Connection.WriteLn(´STOP´) end else if wTipo = UpperCase(´:3´) then begin Peer.Connection.WriteLn(´BLOCK´) end else if wTipo = UpperCase(´:4´) then begin Peer.Connection.WriteLn(´LIBERA´) end else if wTipo = UpperCase(´:5´) then begin Peer.Connection.WriteLn(´#REBOOT´) end else if wTipo = UpperCase(´:6´) then begin Peer.Connection.WriteLn(´MSG´) end else end; finally TCPServer.Threads.UnlockList; end; end;
e no client tenho uma Trhead assim:
procedure TReadingThread.Execute;
var
Command,cmd : String;
begin
With fMain do
begin
repeat
Command := UpperCase(FConn.ReadLn);
cmd := Command;
if Command = ´NET´ then
begin
FConn.WriteLn(IdTCPClient.Socket.LocalName+ ´ Desconectado do Servidor´);
lbStatus.Items.Insert(0,Command);
end;
if Command = ´BLOCK´ then
begin
FConn.WriteLn(IdTCPClient.Socket.LocalName+ ´ Bloqueado com sucesso!´);
lbStatus.Items.Insert(0,Command);
end;
if Command = ´#SHUTDOWN´ then
begin
FConn.WriteLn(IdTCPClient.Socket.LocalName+ ´ Desligado com sucesso!´);
lbStatus.Items.Insert(0,Command);
end;
if Command = ´LIBERA´ then
begin
FConn.WriteLn(IdTCPClient.Socket.LocalName+ ´ Liberado com sucesso!´);
lbStatus.Items.Insert(0,Command);
end;
if Command = ´REBOOT´ then
begin
FConn.WriteLn(IdTCPClient.Socket.LocalName+ ´ Reiniciado com sucesso!´);
lbStatus.Items.Insert(0,Command);
end;
if Command = ´TELA´ then
begin
FConn.WriteLn(´Tela copiado da Estação: ´ + IdTCPClient.Socket.LocalName);
lbStatus.Items.Insert(0,Command);
end;
if Command = ´STOP´ then
begin
FConn.WriteLn(IdTCPClient.Socket.LocalName+ ´ Tempo parado com sucesso!´);
lbStatus.Items.Insert(0,Command);
end;
cmd := UpperCase(Trim(Copy(cmd, 1, Pos(´:´, cmd)-1)));
if cmd = ´!´ then
begin
lbStatus.Items.Insert(0,´Liberado!´);
Button2.Enabled := True;
end
else
if cmd = ´?´ then
begin
lbStatus.Items.Insert(0,Command);
Button2.Enabled := False;
end;
until not IdTCPClient.Connected;
end;
end;
lembra? Ela ainda está incompleta, mais estou desenvolvendo primeiro o server, e fiz o código acima somente para testar, ainda não tá 100¬, mais acho que o caminho é por ai...
Eu tava olhando um dia desses o [b:11672851a1]Projeto Lan-House[/b:11672851a1], mais percebi que o pessoal abandonou ou estão se comunicando por outro lugar, pois, as mensagens que estão lá são muito antigas...
21/03/2006
Massuda
21/03/2006
Paullsoftware
Obrigado mais uma vez grande amigo Massuda! qq coisa resgato esse tópico! :roll:
24/03/2006
Paullsoftware
resolvi resgatar esse tópico, para ficar tudo em um único local, estou com outra dúvida e não sei se é possível fazer essa fasanha...
como faço para pegar o nome da estação através do servidor, digo isso porque estou fazendo assim:
wEstacao := IdTCPClient.Socket.LocalName +´ - ´+IdTCPClient.Socket.Binding.IP;
quando o cliente manda algo para o server em envio junto o nome dele, mais gostaria de saber se tem como fazer isso através do servidor mesmo..
como os Sockets fazem... RemotHost e RemotAddress, é possível fazer com indy :?: :?:
24/03/2006
Massuda
procedure TExemplo.IdTCPServer1Connect(AThread: TIdPeerThread); begin // AThread.Connection.Socket.Binding.PeerIP = IP do cliente // AThread.Connection.Socket.Binding.PeerPort = porta do cliente end;
24/03/2006
Paullsoftware
procedure TExemplo.IdTCPServer1Connect(AThread: TIdPeerThread); begin // AThread.Connection.Socket.Binding.PeerIP = IP do cliente // AThread.Connection.Socket.Binding.PeerPort = porta do cliente end;
certo, hoje eu to fazendo como disse acima, na hora que o cliente conecta envio a seguinte informação:
var
wEstacao:String;
begin
...
wEstacao := IdTCPClient.Socket.LocalName +´ - ´+IdTCPClient.Socket.Binding.IP;
SendCmd(´+´,wEstacao);//onde SendCmd é um procedure que criei para enviar mensagens para o servidor com um determinado identificador seria o mesmo que: [b:def03de3b4][i:def03de3b4]IdTCPClient.WriteLn(´+;´ + wEstacao);[/i:def03de3b4][/b:def03de3b4]. Então, eu envio essas informações e o server trata elas assim:
procedure TfMain.TCPServerConnect(AThread: TIdPeerThread); var Client : TSimpleClient; Cmd,Msg : String; begin Msg := AThread.Connection.ReadLn(); Cmd := Trim(Copy(Msg, 0, Pos(´:´, Msg) -1)); Msg := Trim(Copy(Msg, Pos(´:´, Msg) +1, Length(Msg))); if Cmd = ´+´ then begin AThread.Connection.WriteLn(´;: NOME DA ESTAÇÃO NA REDE: ´+Msg); AThread.Connection.WriteLn(´#BLOCK´); Client := TSimpleClient.Create; Client.Name := Trim(Copy(Msg, 0, Pos(´-´, Msg) -1)); Client.DNS := Trim(Copy(Msg, Pos(´-´, Msg) +1, Length(Msg))); ; Client.ListLink := lbClients.Items.Count; Client.Thread := AThread; lbClients.Items.Add(Client.Name+ ´ - ´+Client.DNS); AThread.Data := Client; Clients.Add(Client); lbStatus.Items.Insert(0,UpperCase(Client.Name)+ ´ Conectou agora: ´ + FormatDateTime(´DD/MM/YYYY HH:MM:SS´,Now) ); end;
só que pensei que haveria uma fora de ´pegar´ o nome/ip do cliente e não ´ler´ como fasso. mais valeu...
estou pensando em fazer tudo no server (banco/programação/comandos/contagem do tempo, etc...) tudo no server, nos clientes pensei em mandar somente o exe... seria vantagioso? :roll:
24/03/2006
Massuda
24/03/2006
Paullsoftware
en entendi, até fiz um teste aqui e funcionou... vlw
quanto a isso vou dar mais uma vasculhada pelo fórum :wink:
05/04/2006
Paullsoftware
toda vez que um cliente conecta ao sevidor eu jogo ele em uma lista (Listbox) e tb armazeno suas informações em [b:006f65b589]TThreadList[/b:006f65b589] até ai tudo bem, quando eu seleciono um cliente no listbox ele mostra as informações sobre ele como IP, tempo de acesso e outras informações...
O problema é que o meu ListBox está preparado para ser organizado em ordem alfabética e quando e quando o último cliente conecta ao servidor e esse fica sendo o primeiro da lista e dou um clique sobre ele aparece as informações sobre o primeiro cliente a ser conectado.
a pesquisa é feita assim hoje:
SelClient := pclient(Clients.LockList.Items[lbClients.ItemIndex]);
como faço para fazer essa pesquisa pelo no do item no listbox e não o índice?
Clique aqui para fazer login e interagir na Comunidade :)