PDA

Visualizza la versione completa : [DELPHI] Semplice prog di PING


Anuelicon
17-10-2005, 13:15
Ciao a tutti, vorrei realizzare una piccola applicazione che verrà messa nell'esecuzione automatica di windows.
Questa App del client dovrà semplicemente temtare di connettersi ad intervalli regolari di 60 secondi ad un determinato indirizzo ip:porta.
Non deve fare nient'altro, quindi non deve essere un'applicazione aperta sul descktop e/o ridotta a icona, mi piacerebbe che si mettesse subito in background e cominciasse a provare ignorando il fatto che la macchina magari non è connessa in rete(in quel momento).
Nel lato server ci sarà un'applicazione simile in ascolto su ip:porta che se riceve il ping segnala immediatamente (tramite baloon o un MessagePanel) che il client id_client si è ora online.
Io ho un po di esperienza in programmazione Java ma mi è stato consigliato di utilizzare Delphi perchè in Java risulta difficile rendere "invisibile" un programma.
In delphi ho poca esperienza. Vi chiedo aiuto, qualsiasi consiglio, segnalazione di epsempi o pezzi di codice saranno preziosi.
Vi ringrazio.
Ciao :ciauz:

billiejoex
17-10-2005, 14:45
Tolto che non conosco Delphi quanto da te descritto non è da considerarsi un programma di ping.
Ping, infatti, utilizza il protocollo ICMP che non prevede l'utilizzo di porte e allo stesso modo non prevede un concetto di "connettività" in senso classico (non viene instaurata una vera e propria connessione tra i due host).
Per fare quanto da te descritto ti dovrai affidare al protocollo TCP sviluppando una banale applicazione client/server utilizzando le librerie socket.

Con TCP:
Lato server binderai un socket su una determinata porta.
Lato client creerai un ciclo che ogni tot secondi tenterà di connettersi a ip_remoto:porta portandosi dietro un payload contenente una stringa del tipo: "sei online?".
Il server legge la stringa. Se è == a "sei online" risponde con un pacchetto contenente una stringa == "si sono online".
Se il client riceverà tale stringa stamperà a video una scritta (o un pop-up o quello che preferisci).


Con ICMP:
Se preferisci il classico 'ping' lato client dovrai scrivere un applicativo che ogni tot secondi manda un ICMP di tipo ECHO(request) alla macchina remota. Se la macchina remota risponde con un ECHO_REPLY significa che è online.
Questa scelta risulta essere più semplice in quanto dovrai scrivere un solo programma dato che a rispondere al tuo 'ping' ci penserà il kernel della macchina remota in modo automatico ma allo stesso tempo risulta essere un pelino più complicato per quanto riguarda l'implementazione.
Naturalmente sulla macchina remota non ci dovrà essere un firewall che droppa il protocollo ICMP. Per l'implementazione in Delphi non ti so aiutare ma in linea di massima la creazione di un programma di ping è relativamente semplice ed è uguale per tutti i linguaggi:
crei un pacchetto IP in cui incapsulerai l'ICMP di tipo ECHO che spedirai tramite un socket di tipo RAW e con lo stesso resterai in ascolto per eventuali risposte.
Cerca con google "ping in delphi" e prova a dare uno sguardo a questo topic:
http://forum.html.it/forum/showthread.php?s=&threadid=876002&highlight=icmp

Saluti

Anuelicon
17-10-2005, 15:28
Prima di tutto ti ringrazio per la risposta...Nel titolo ho sbagliato, non devo lavorare con ICMP, devo creare una connessione TCP, il mio problema è più che altro tentare di creare la connessione ogni tot sec, il programmino deve lavorare totalmente nascosto al massimo con l'icona affianco all'ora di sistema, il client utilizza connessioni a internet saltuariamente, il mio problema è proprio far si che il server sappia quando il client è connesso, Client/server mantengono la connessione finchè il client non si disconnette; dal quel momento il programma riprende i tentativi...
I miei problemi non sono tanto nella creazione della connessione e nel dialogo tra client e server, ho problemi a realizzare un programma invisibile che tenti le connessioni e che continui a tentare ignorando le eccezioni di una connessione non presente.

billiejoex
17-10-2005, 15:44
Non vedo dove sta il problema. Per creare un'applicazione 'invisibile' non ti basta creare un semplice eseguibile che rimane in background come semplice processo?

il client utilizza connessioni a internet saltuariamente, il mio problema è proprio far si che il server sappia quando il client è connesso
Anche qui non vedo il problema. Come ho scritto sopra basta che lato client metti in esecuzione automatica un programma (sotto forma di processo 'invisibile da GUI') che ogni tot secondi cerca di instaurare una connessione col server remoto.
Se tale connessione avviene il server renderà noto che client è connesso.
Cos'è che non riesci a implementare? Fai domande più specifiche.

I miei problemi non sono tanto nella creazione della connessione e nel dialogo tra client e server, ho problemi a realizzare un programma invisibile che tenti le connessioni e che continui a tentare ignorando le eccezioni di una connessione non presente.
Per l'"invisibilità" vale quanto ho detto sopra.
Per non fare bloccare l'applicativo nel caso in cui non riesca a instaurare la connessione ti basta gestire le eccezioni sollevate dal socket e continuare a rimanere dentro il ciclo del 'tentativo' ogni tot secondi.
Dai un occhio a qualche tutorial di socket prog in delphi.

Anuelicon
17-10-2005, 16:01
Ci sto lavorando un po e devo dire che non è difficile utilizzare Delphi, ora quindi faccio una domanda specifica:
Come si fa a far andare il programma in completo background?
Grazie infinite

billiejoex
17-10-2005, 16:05
Scusa ma se nel codice non includi alcuna interfaccia grafica e lanci semplicemente l'eseguibile il programma è in background, sotto forma di processo. Se non tramite il taskmanager o simili l'utente non ha modo di vederlo attivo.
Intendi forse nascondere anche il processo? In tal caso la cosa si fa complicata, ancor di più se sei neofita nel linguaggio.

alka
17-10-2005, 16:23
Come ti è stato suggerito, il protocollo ICMP non ti serve in questo caso, e su questo fattore hai convenuto anche tu.

Per quanto riguarda il programma che devi realizzare, il protocollo più adatto dovresti sceglierlo in base al tipo di connessione che desideri instaurare. Mi spiego, se il colloquio tra i due PC è un "connessione+botta+risposta+disconnessione", mantenendo però il PC connesso al server per tutta la durata in cui esso deve essere considerato "online", allora il protocollo TCP è quello più indicato; se invece devi solamente inviare una notifica al server senza usufruire di uno stato di connessione permanente, allora ti basterebbe usare il protocollo UDP, molto più rapido in questo senso.

Approfondendo il lato tecnico, in Delphi puoi usare i componenti Indy (http://www.indyproject.org) per creare un client e un server appropriati e scambiare dati tramite socket.

I componenti sono presenti nelle più recenti distribuzioni di Delphi; in caso contrario, li trovi nel sito ufficiale.

In merito all'esecuzione in background, come desideri che si comporti esattamente il tuo programma? Fino a che punto vuoi nasconderlo? Partendo da un'applicazione comune dotata di un form principale, il massimo che puoi ottenere è un programma che sia visibile solamente come processo nel Task Manager, oltre non credo tu possa andare.

In quel caso, forse basterebbe creare un'applicazione Windows disabilitando la visualizzazione del form principale (Application.ShowMainForm impostata a False) e dando vita ad un ciclo che tenta di connettersi ad intervalli regolari, inviando in "PING", intercettando eventuali eccezioni (ad esempio, i timeout)...in sostanza, governando l'intero sistema che devi mettere in piedi.

Ciao! :ciauz:

Anuelicon
18-10-2005, 10:33
Ragazzi vi posto qui il mio codice fatto fino ora...so bene che i programmatori avranno qualche convulsione ma considerate che è la seconda volta che uso Delphi e la prima volta che lo uso per la rete :)
Ho aperto una nuova applicazione e l'unico oggetto che ho trascinato nella form è stato TIdTCPClient
Nell'Object Inspector ho potuto settare l''host del server e la porta e per semplicità ho cambiato nome all'oggetto in TCP.
Facendo doppio click sull'oggetto nella form mi si apre il codice e ha appena creato una procedure assiociata al doppio click: procedure TForm1.TCPConnected(Sender: TObject);
qui ho inserito questo codice
begin

if (TCP.Connected=false) then
begin
repeat
sleep(5000);
TCP.Connect();
until TCP.Connected=true;
end
else
begin
sleep(5000);
TCP.Disconnect;
end;
end;

Andando poi negli events dell'Obj Insp ho associato TCPConnected sia all'evento OnConnect che all'evento OnDisconnect...l'ho asiocato anche all'evento OnActivate della Form1.
Ora, il mio codice sarà sicuramente migliorabile per quello che devo fare, però funziona, il lato server (fatto in java:) ) mi comunica la connessione del client ogni 5 sec...Il mio problema ora è nel gestire le eccezioni se il client è scollegato dalla rete.
Infatti appena arrica a TCP.Connect() mi segnala EIdSocketError e blocca tutto...
Andando in giro per la rete ho trovato e provato a usare:
try ...except on EIdSocketError do continue;
Mettendo anche EIdSocketError = class(EIdSocketError) ma mi dice che non conosce EIdSocketError, credevo chefosse nella Uses SysUtils !! :(
Come faccio a dirgli di ignorare tutti gli errori quando non è connesso e di continuare a riprovare??
Grazie a tutti per la gentile disponibilità...

alka
18-10-2005, 10:40
Originariamente inviato da Anuelicon
Come faccio a dirgli di ignorare tutti gli errori quando non è connesso e di continuare a riprovare??

Semplicemente


try
// ...istruzione che genera potenzialmente eccezioni
except
end;

Ciao! :ciauz:

Anuelicon
18-10-2005, 11:13
Ciao, ho fatto come mi hai segnalato

try

TCP.Connect(); // è l'istruzione che genera l'errore nel Debug

except
end;

Una volta avviato si presenta questa finestra di errore:

Debugger Exception Notification

Project xyz.exe raised excpetion class EIdSocketError with message 'Socket Error # 11004'. Process stopped. Use Step or Run to continue.
:messner:

Loading