TIMESERVER V1.0.3

cs_Christophe67 Messages postés 80 Date d'inscription lundi 2 juin 2003 Statut Membre Dernière intervention 15 juin 2012 - 8 mars 2010 à 21:31
chesnetda Messages postés 9 Date d'inscription mercredi 31 mai 2006 Statut Membre Dernière intervention 8 février 2010 - 15 mars 2010 à 10:57
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/51413-timeserver-v1-0-3

chesnetda Messages postés 9 Date d'inscription mercredi 31 mai 2006 Statut Membre Dernière intervention 8 février 2010
15 mars 2010 à 10:57
C'est pour cela que j'ai parlé "d'une sorte de "Halt" et pas de "halt" ;-)
Puisqu'on rentre dans les détails, L'aide de Delphi7 indique " Appelez Terminate pour terminer par programme l'exécution d'une application. En appelant Terminate au lieu de libérer l'objet application, vous permettez à l'application de s'arrêter d'une manière plus ordonnée." et la version anglaise précise "Terminate calls the Windows API PostQuitMessage function to perform an orderly shutdown of the application. Terminate is not immediate. Terminate is called automatically on a WM_QUIT message and when the main form closes."
@Christophe67: il me semble avoir déjà lu sur ce site un (ou des ?) débat(s) sur le thème Terminate/Close, si tu veux en savoir plus.
Cordialement
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
15 mars 2010 à 10:39
Salut,
effectivement, si la fenêtre est en cours de création elle ne peut techniquement pas encore être détruite et libérée. Cependant, Terminate ne constitue pas un "Halt" à proprement parler car il ne tue pas le processus directement. Il s'occupe de libérer tout ce qui peut l'être (fenêtres du projet, composants, objets en variable globale), appelle les API windows qu'il faut et ensuite seulement termine le processus. Pour effectuer un Halt (pas de libération de mémoire, on termine net le processus, on peut utiliser la commande Halt ou bien l'API ExitProcess. Mais c'est violent et recommandé que dans les cas extrêmes (par exemple une application en trop mauvais état, qui si elle continue causerait des dommages irréparables sur le disque).

Cordialement, Bacterius !
chesnetda Messages postés 9 Date d'inscription mercredi 31 mai 2006 Statut Membre Dernière intervention 8 février 2010
15 mars 2010 à 10:25
Bonjour Christophe67,
Je crois que l'explication à ton soucis de Close/Terminate est simplement qu'on ne peux pas demander à une From de se fermer "normalement" alors qu'elle est en train d'être créé. Terminate provoque un arrêt brutal de l'application (une sorte de "Halt") et n'est pas soumis aux contraintes que Close.
Cordialement
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
14 mars 2010 à 04:36
@Cari : ah, intéressant, je vais regarder ça de plus près quand j'aurai un peu de temps libre :)

Cordialement, Bacterius !
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
14 mars 2010 à 04:29
@Mauricio
«Pour la petite histoire, ton code m' a rappelé un bug de la Playstation3 en Février de cette année...»

Ca doit être le tsunami du bug de l'an 2000. lol

@Bacterius
Après recherches, il semble bien que la solution pour synchroniser deux horloges distantes existera bientôt grâce au CERN et à Einstein.

@@Christophe67
Je peux me tromper, mais il me semble que ton application sera obsolète bien avant les sites que tu utilises.
Bacterius Messages postés 3792 Date d'inscription samedi 22 décembre 2007 Statut Membre Dernière intervention 3 juin 2016 10
14 mars 2010 à 02:50
"Je passe à autre chose, j'ai perdu trop de temps sur ce micro-projet."
o_O' à la chaîne

De toute façon, tu ne peux pas synchroniser "exactement" le temps, car :
- l'horloge atomique a une très grande précision, mais ton ordinateur n'en a qu'une très faible (à la seconde ou peut-être milliseconde)
- il faut prendre en compte le ping depuis ton ordinateur jusqu'au serveur, et au retour. Bref le temps sera faux de quelques millisecondes (voire secondes si l'internet est lent).

Cordialement, Bacterius !
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
12 mars 2010 à 10:32
Pour la petite histoire, ton code m' a rappelé un bug de la Playstation3 en Février de cette année:
cette dernière se croyait le 29 Février au lieu du 1er Mars (année pas bisextile du tout!).
Le résultat est qu' elle n' avait pas son horloge "synchronisée" avec celle du Serveur de jeu en réseau (appelé Playstation Network) et donc, pas moyen de lancer une partie réseau.

Voilà, c' est tout :)

A+

PS: c' est bien ce citer ces sources ...
cs_Christophe67 Messages postés 80 Date d'inscription lundi 2 juin 2003 Statut Membre Dernière intervention 15 juin 2012
11 mars 2010 à 16:10
v 1.0.3 fonctionne comme je le souhaite.

Plus la peine de perdre des millisecondes à transformer la structure TDateTime en TSystemTime et d'utiliser SetLocalTime, en effet il existe une fonction interne au composant qui fait déjà cela : SNTP.SyncTime;
Contrairement aux conseils donnés je n'ai plus de problèmes en réutilisant Application.Terminate au lieu de Close;

Je passe à autre chose, j'ai perdu trop de temps sur ce micro-projet.
cs_Christophe67 Messages postés 80 Date d'inscription lundi 2 juin 2003 Statut Membre Dernière intervention 15 juin 2012
11 mars 2010 à 14:35
Re,

bon j'ai essayé ceci :

Tout d'abord le composant TidSNTP est mis à Active = False

procedure TTimeServ.FormCreate(Sender: TObject);
begin
if not FileExists(GetCurrentDir+'\servers.txt') then
begin
ShowMessage('le fichier "servers.txt" n''est pas dans le répertoire');
Close; <-- j'ai aussi essayé avec Exit
end
else
begin
ListeServeur.Items.LoadFromFile(GetCurrentDir+'\servers.txt');
ListeServeur.ItemIndex := 0;
LabServeur.Caption := ListeServeur.Items[ListeServeur.ItemIndex];
SNTP.Host := ListeServeur.Items[ListeServeur.ItemIndex];
SNTP.Active := True;
end;
end;

J'ai toujours mon erreur socket #10054.
J'arrive à passer outre si je force un serveur en inscrivant son nom directement dans les propriétés (Host => ntp.imag.fr )mais ce que je ne comprends pas c'est que le programme affiche le fichier manquant et s'exécute comme si tout allait bien alors qu'après ShowMessage il rencontre Close qui devrait mettre fin à l'application.
cs_Christophe67 Messages postés 80 Date d'inscription lundi 2 juin 2003 Statut Membre Dernière intervention 15 juin 2012
11 mars 2010 à 09:42
Le choix du fichier c'est pour permettre à l'utilisateur d'ajouter ou modifier la liste, en effet beaucoup de serveurs type strate2 ne sont pas en accès libres. Ceux que j'ai mis le sont mais ca pourrait changer.

Salutations.
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
11 mars 2010 à 00:56
Perso, dans une petite application telle que celle-là je ne mettrais pas de fichier mais je coderais les liens vers les serveurs en dur.
Mais bon! C'est un choix...

Autre chose qui me turlupine, et au risque de paraître lourd... :)

Comment fait-on pour synchroniser 2 horloges très distantes ?
Je pense au vaiseau qui ira un jour sur Mars avec des humains à bord. Je pense que l'horloge embarquée devra être inpeccablement synchronisée avec les ordinateurs de suivi sur terre.

Y'a-t'il un truc ?
cs_Christophe67 Messages postés 80 Date d'inscription lundi 2 juin 2003 Statut Membre Dernière intervention 15 juin 2012
10 mars 2010 à 15:17
Merci,

J'y avais pensé mais je pensais qu'on pouvait s'en affranchir avec try ... except puisque la routine était dérivée sur le ShowMessage puis Close;
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
10 mars 2010 à 14:34
if not FileExists('serveurs.txt') then begin
ShowMessage('blabla');
Exit; end
else begin
...
end;
cs_Christophe67 Messages postés 80 Date d'inscription lundi 2 juin 2003 Statut Membre Dernière intervention 15 juin 2012
10 mars 2010 à 12:50
Par contre j'en profite pour parler d'une erreur que je ne sais pas corriger.
Si on supprime le fichiers "serveurs.txt" et qu'on lance le programme il s'ouvre en chaîne une fenêtre m'indiquant une erreur #10054, c'est très disgracieux et embêtant.
J'ai pensé que c'était dû au composant qui n'a pas de host déclaré dans ses propriétés, j'ai essayé de corriger en placant la valeur "Active" du compo à false lors du FormCreate et la mettre à "true" plus loin mais malgré la boîte de dialogue signalant l'absence du fichier, le programme semble s'exécuter quand même. Comment corriger ou traiter l'erreur ?
cs_Christophe67 Messages postés 80 Date d'inscription lundi 2 juin 2003 Statut Membre Dernière intervention 15 juin 2012
10 mars 2010 à 12:09
Merci Delphiprog,

Code corrigé mais bien que je vois ce que tu veux dire pour le "ListeServeurClick(nil);", j'ai préféré faire un doublon à la place plutôt que diffuser un code incorrect.
Pour le code par jour cela dépend de mon avancée, comme je suis en période de découverte les idées fusent mais c'est surtout car j'avais besoin de ce programme et que les seules versions proposées étaient soient payantes (je suis accroc du freeware), soient avec des fenêtres de pubs.

Salutations.
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
9 mars 2010 à 19:32
Deux remarques ...

1/- Je déconseille vivement d'utiliser ce type de code :
// On affiche son nom et on le valide
ListeServeurClick(nil);

Pourquoi ?
Dans un grand projet, on est souvent amené à transtyper le paramètre sender reçu en argument. Si un développer passe nil comme valeur, c'est la cata et on a droit à une belle violation d'accès !
La solution ?
Dans l'évènement click de l'objet Listserveur, on appelle une méthode (en général déclarée de portée privée). Cette même méthode devient alors accessible dans FormCreate et il suffira de l'appeler.
Dans ce code, qui tient sur une page écran, ce n'est pas critique. Sur des projets de grande envergure, ça peut devenir problématique surtout si on travaille en équipe de développement.

2/- Deuxième remarque :
Eviter l'employer de Application.Terminate, surtout quand on utilise des ensembles de données car, dans ce cas, ils ne seront pas fermés et les éventuels verrous de table ou d'enregistrement pas libérés. Un simple appel à la méthode Close, en revanche, permettra de sortir proprement.

Pour le reste, je finirai en faisant remarque qu'il n'est pas utile de déclarer la variable TimeServ dans la partie interface puisqu'elle devient alors modifiable par une autre unité. Sa place serait plus appropriée dans la partie implementation.

Dis Christophe, tu penses continuer à publier un code par jour ?
cs_Christophe67 Messages postés 80 Date d'inscription lundi 2 juin 2003 Statut Membre Dernière intervention 15 juin 2012
9 mars 2010 à 10:22
En théorie oui, puisque la précision d'une horloge atomique est de l'ordre du millionième de seconde par an en + ou en - .
En pratique non, si l'on tiens compte des pertes de charge lors des transferts entre "horloge atomique -> serveur strate 1 -> serveur strate 2 -> PC -> Programme -> Heure système" on a bien dû perdre quelques centaines de millisecondes. mais disons que c'est le réglage le plus précis.

Salutations.
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
9 mars 2010 à 04:36
«On synchronise notre PC avec l'horloge atomique au millionnième de seconde»...

Est-ce vraiment possible ?
cs_Christophe67 Messages postés 80 Date d'inscription lundi 2 juin 2003 Statut Membre Dernière intervention 15 juin 2012
8 mars 2010 à 22:43
C'est bon, c'est corrigé.
En fait j'ai lu dans un article qu'il fallait utiliser "SetSystemTime" alors qu'en fait c'est mieux "SetLocalTime".
Désolé pour le dérangement.

Salutations
cs_Christophe67 Messages postés 80 Date d'inscription lundi 2 juin 2003 Statut Membre Dernière intervention 15 juin 2012
8 mars 2010 à 22:24
Trouvé, il faut cocher la propriété "Exécuter ce programme en tant qu'administrateur".
Mais toujours un bug, rajoute +1h à l'heure locale.
cs_Christophe67 Messages postés 80 Date d'inscription lundi 2 juin 2003 Statut Membre Dernière intervention 15 juin 2012
8 mars 2010 à 21:31
Bon ... y'a un bug , çà fonctionne très bien quand je compile et teste à partir de Delphi mais pas en dehors.
Désolé j'ai posté trop vite je vais corriger çà. En plus j'ai oublié de mettre la liste des serveurs.
Mea culpa, trop pressé.
Rejoignez-nous