Fórum Programinha pra verificar a conexao em rede #299897
19/10/2005
0
Preciso fazer um programinha assim:
numa máquina ficará um servidor, pode ser idTCP ou qualquer outro
na outra máquina ficará um client, pode ser idTCP ou qualquer outro.
quero saber quantas vezes por dia o cliente perde conexão com o server, então, se o cabo for desconectado, o server for desligado, um problem de tráfego, virus etc me desconectar ou o próprio Satanás soprar os cabos da Telefônica eu gostaria que aparecessa na tela do client uma messagebox (´se ferrou mané´);
fiz uma usando idTCPserver e client, mas ficou meio porco porque:
1) depois do client conectado, ele não percebe que foi desconectado, só se tentar enviar um dado ou tentar conectar de novo, e eu não vou colocar um timer pra ficar fazendo isso.
2) uma máquina pode estar conectada na rede, mas o idTCP pode não saber ou não se conectar se a configuração da máquina só permitir conexão icmp, udp etc (se bem que isso não é problema, já que eu quero monitorar só o tcp)
não sei como fazer tipo um ping em delphi.
valew!
Vitor Rubio
Curtir tópico
+ 0Posts
19/10/2005
Massuda
O que você pode fazer é enviar periodicamente algo do cliente para o servidor (isso é o PING) ou mandar algo do servidor para o cliente (geralmente isso se chama KEEP ALIVE); o PING é mais fácil de fazer.
No cliente, coloque um timer e periodicamente envie o PING para o servidor; faça o servidor responder algo útil (costuma-se por algo relacionado com tempo, assim dá para medir quanto tempo demora para ir do cliente para o servidor).
[quote:02ab67e090=´vitor^_^´]... eu não vou colocar um timer pra ficar fazendo isso.[/quote:02ab67e090]Não sei como faria sem um timer.
Gostei + 0
19/10/2005
Vitor Rubio
Eu envio um comando ou mensagem do client pro server, mas eu não sei como fazer pro server responder, nem como pegar essa resposta no client. Alem disso, mesmo com o server desativado, a máquina ainda pode estar na rede....
Gostei + 0
19/10/2005
Massuda
No TidTCPServer, no Object Inspector, selecione a propriedade CommandHandlers e dê um clique duplo (ou clique no botão com ...); clique no botão ´Add new´. No Object Inspector, na propriedade Command, digite PING e na propriedade Response dê um clique duplo (ou clique no botão com ...) e digite OK. Isso deve ser suficiente se você não criou um (tratador de) evento para o evento OnExecute do servidor.
[quote:e2a81af454=´vitor^_^´]...Alem disso, mesmo com o server desativado, a máquina ainda pode estar na rede....[/quote:e2a81af454]Concordo, com isso, mas acho que aí o problema seria outro, também ´fácil´ de resolver. O problema seria garantir que o servidor está sempre rodando. Nesse caso, você pode fazer algo como oIBGuardian do Interbase, que é um programa que checa se o servidor IB está rodando e, se ele não estiver, ele iniciar o servidor. Ou você está pensando em algo diferente?
Gostei + 0
19/10/2005
Vitor Rubio
Apenas, se fosse possivel saber se a máquina do servidor está conectada, por qualquer protocolo ou porta (tipo pingar ele) eu gostaria de aprender como.
Com relação ´PING´, beleza, o idTCPServer vai me responder ´OK´, mas como eu pego esse ´OK´ no meu client? tem q dar readln no server?
Gostei + 0
19/10/2005
Massuda
Gostei + 0
19/10/2005
Vitor Rubio
Valeu Massuda!
Gostei + 0
21/10/2005
Vitor Rubio
criei um comandinho ´snap´ que quando eu mando para o server, o server faz um snapshot da sua tela atual, joga num bitmap e depois joga numa memory stream.
como eu faço pra passar essa stream do servidor pro cliente?
Assim eu poderia visualizar numa form...
Valew!
Gostei + 0
21/10/2005
Massuda
SuaStream.Position := 0; // posiciona no início SuaConexão.WriteInteger(SuaStream.Size); SuaConexão.WriteStream(SuaStream);
var Size: Integer; ... Size := SuaConexão.ReadInteger; SuaConexão.ReadStream(SuaStream, Size);
Gostei + 0
31/10/2005
Vitor Rubio
primeiro porque o server não tem os métodos writeinteger e writestream, então eu tive que adicionar um client no programa servidor pra escrever os dados no proprio server. (acho que isso deve ser normal)
Depois disso, ao usar o client para escrever a stream no server, ocorre uma exception dizendo que foi excedido o número máximo de linhas que pode ser enviado. Não adianta eu setar a propriedade maxlinelength pra 0 ou -1, continua com o mesmo erro. (alem disso eu acho que essa propriedade é o tamanho maximo de uma linha, e não omaximo de linhas)
Continuo sem saber como enviar e receber um stream. meu stream não é muito grande, o número de bytes não chega nem perto de exceder o limite de um integer. Aliás, ele tem uns 50000 bytes no máximo.
Obrigado pela força! ^^
Gostei + 0
01/11/2005
Firekiller
var
s:TMemoryStream;
b:String;
i:Integer;
s := TMemorySTream.create;
i := Socket.ReceiveLength;
while i > 0 do begin
Socket.ReceiveBuf( b , i);
s.WriteBuf( b , length(b) );
sleep(200);
i := Socket.ReceiveLength;
end;
Estes componentes são mais simples para se trabalhar (pelo menos na minha opinião), porém já estão deixados de lado... atualmente utiliza-se os da palheta Indy mesmo (os que você está usando), porém eu acho eles mais complicados.
Gostei + 0
01/11/2005
Vitor Rubio
Obrigado pela ajuda :wink:
Gostei + 0
01/11/2005
Massuda
// no comando SNAP do servidor procedure TForm1.IdTCPServer1CmdSnapCommand(ASender: TIdCommand); var Stream: TMemoryStream; begin Stream := TMemoryStream.Create; try // gera um bitmap e copia para Stream Stream.Position := 0; // posiciona no início ASender.Thread.Connection.WriteInteger(Stream.Size); ASender.Thread.Connection.WriteStream(Stream); finally Stream.Free; end; end; // no cliente procedure TForm2.PedeSnapshot(var ASnapshot: TBitmap); var Stream: TMemoryStream; Size: Integer; begin Stream := TMemoryStream.Create; try IdTCPClient1.Writeln(´SNAP´); Size := IdTCPClient1.ReadInteger; IdTCPClient1.ReadStream(Stream, Size); // copia o bitmap da Stream finally Stream.Free; free; end;
Gostei + 0
03/11/2005
Vitor Rubio
Quando eu paro a execução dos 2 timers (cliente e servidor) ainda tem um monte de strings ´ok´ na fila. Se eu sou um writeinteger no servidor, ele entra depois desses ´ok´. Se eu dou um readinteger no cliente, ele vai tentar transformar esses 8 bytes te texto num número, transsformando assim num número esdrúxulo e uma stream errada.
precisaria saber como se limpa as linhas do server.
mas estamos quase conseguindo ^^
Gostei + 0
03/11/2005
Massuda
Gostei + 0
04/11/2005
Vitor Rubio
Eu nem expliquei direito como que o programa funcionava, seguinte:
Tenho um banco de dados interbase num servidor que todo mundo (as outras máquinas) conhecem e sabem onde está. Tem uma tabela nesse banco que meu programinha server fica gravando o endereço IP dele a cada 30 minutos (isso porque o ip pode mudar quando a máquina for reiniciada, é dinamico). É por isso que tem timer no server também. Nada haver né? Aliás, esqueci de falar, ambos, tanto o client como o server iniciam junto com o windows, porque eu criei uma entrada lá no run do registro.
A cada 2 segundos o cliente ´pinga´ o server, se não conseguir conexão, ele verifica na tabela do banco de dados interbase se o IP não mudou, se mudou ele pega o novo, se mesmo assim ele não conseguir conectar ele desiste. Ah, antes de pingar a primeira vez ele verifica qual é o primeiro ip que tá lá né? (dãn).
Bom, eu consegui mandar e ler a stream fazendo uma gambiarra. Eu poderia usar um outro server em outra porta pra isso, e outro client, mas o que eu fiz: Quando eu congelo os 2 timers, eu dou um write(´|´) no server (não writeln). No cliente eu dou um readln(´|´). Ou seja, como o novo terminador é ´|´ ao invés de #13, ele vai ler todos os bytes até encontrar o ´|´, inclusive ele mesmo. O único problema é se minha stream contiver um ´|´ também.... mas aí é muita sacanagem do murphy hauahau.
Depois de mandar/receber os streams, eu mando/recebo um ´|´ de novo, pra zerar tudo, e reativo os timers.
Antes de mandar o stream eu compacto o stream usando a zlib, pra ficar mais levinho, (tcompressionstream etc...) depois descompacto na hora que receber, pra mostrar.
Consegui fazer o snapshot e até ´filmar´ a tela do server, fazendo snapshots consecutivos a cada 15 milissegundos.... Funcionou durante alguns minutos... mas ficou pesadão e lentão... mas não importa, aos poucos agente vai melhorando, já ficou muito melhor com a zlb do que sem heheheeh. Será que eu consigo fazer um VNC? O meu objetivo nem era esse, o meu objetivo na verdade era criar um programa que pudesse mandar imagens de uma camera do server pra minha casa, tipo pra vigilância...
Bom... será que é interessante eu postar o código fonte dele inteiro aki? Ele tem bastante exemplos interessantes de como se usam certas coisas, que eu usei pela primeira vez, como TidTcpserver/client e zlib.
Valeu pela força que vc me deu!
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)