Bonjour,
J'ai un invalid cast type insoluble apres multiples debogage.
Environnement:
Raspbian : uname -a =Linux pi1 4.19.66-v7+ #1253 SMP Thu Aug 15 11:49:46 BST 2019 armv7l GNU/Linux
Lazarus 2.0.12/fpc 3.2.0
composant Indy:Indy 10.6.2

Programme: server domotique (avec du code commun server/client sous delphi11 pour les clients)
Incident: Lors "Formclosequery" de la form principale (umainsrvlaz.pas),
exec la ligne "745" Fserver.Active:=False (dans utdtmreseauw.pas TDTMReseauW.Srv_Deconnecter ) =>Exception invalid cast type
(ligne en gras dans le CODE)
Le serveur a marché pendant plusieurs années, mais après des modifications, impossible de resoudre l'origine
de cet "invalid cast type" a priori interne à INDY.

Merci d'avance de vos conseils éclairés.
bonne journée.


Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
 
===========================
EXTRAIT Log Heapsrc sou terminal:
===========================
pi@pi1:~/dev/domsrvcliv15/domsrvlazv15 $ ./domsrvlaz
 
(domsrvlaz:7291): GLib-GObject-WARNING **: /build/glib2.0-dSIWKl/glib2.0-2.50.3/./gobject/gsignal.c:2524: signal 'populate-popup' is invalid for instance '0x1f8e5b0' of type 'GtkCellView'
WARNING: TPanel.Destroy with LCLRefCount>0. Hint: Maybe the component is processing an event?
Heap dump by heaptrc unit of /home/pi/dev/domsrvcliv15/domsrvlazv15/domsrvlaz
1365961 memory blocks allocated : 119305692/123294344
1299182 memory blocks freed     : 111555270/115498832
66779 unfreed memory blocks : 7750422
True heap size : 16908288
True free heap : 1791856
Should be : 2701992
Call trace for block $7405F180 size 16
  $00782FF0  TIDLISTENERTHREAD__RUN,  line 1101 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdCustomTCPServer.pas
  $007AB880  TIDTHREAD__EXECUTE,  line 435 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdThread.pas
Call trace for block $7405F100 size 12
  $007ACDB8  TIDSCHEDULEROFTHREAD__NEWYARN,  line 212 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThread.pas
  $007AD904  TIDSCHEDULEROFTHREADDEFAULT__ACQUIREYARN,  line 91 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThreadDefault.pas
  $00782FF0  TIDLISTENERTHREAD__RUN,  line 1101 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdCustomTCPServer.pas
  $007AB880  TIDTHREAD__EXECUTE,  line 435 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdThread.pas
  $00782FF0  TIDLISTENERTHREAD__RUN,  line 1101 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdCustomTCPServer.pas
  $007AB880  TIDTHREAD__EXECUTE,  line 435 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdThread.pas
Call trace for block $74047080 size 80
  $00291F0C
  $007AC72C  TIDTHREADWITHTASK__CREATE,  line 736 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdThread.pas
  $007ACCC8  TIDSCHEDULEROFTHREAD__NEWTHREAD,  line 200 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThread.pas
  $007ADAA4  TIDSCHEDULEROFTHREADDEFAULT__NEWTHREAD,  line 137 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThreadDefault.pas
  $007AD8F8  TIDSCHEDULEROFTHREADDEFAULT__ACQUIREYARN,  line 91 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThreadDefault.pas
  $00782FF0  TIDLISTENERTHREAD__RUN,  line 1101 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdCustomTCPServer.pas
  $007AB880  TIDTHREAD__EXECUTE,  line 435 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdThread.pas
Call trace for block $74057110 size 28
  $007AC72C  TIDTHREADWITHTASK__CREATE,  line 736 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdThread.pas
  $007ACCC8  TIDSCHEDULEROFTHREAD__NEWTHREAD,  line 200 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThread.pas
  $007ADAA4  TIDSCHEDULEROFTHREADDEFAULT__NEWTHREAD,  line 137 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThreadDefault.pas
  $007AD8F8  TIDSCHEDULEROFTHREADDEFAULT__ACQUIREYARN,  line 91 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThreadDefault.pas
  $00782FF0  TIDLISTENERTHREAD__RUN,  line 1101 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdCustomTCPServer.pas
  $007AB880  TIDTHREAD__EXECUTE,  line 435 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdThread.pas
Call trace for block $7404F080 size 112
  $007ACCC8  TIDSCHEDULEROFTHREAD__NEWTHREAD,  line 200 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThread.pas
  $007ADAA4  TIDSCHEDULEROFTHREADDEFAULT__NEWTHREAD,  line 137 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThreadDefault.pas
  $007AD8F8  TIDSCHEDULEROFTHREADDEFAULT__ACQUIREYARN,  line 91 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThreadDefault.pas
  $00782FF0  TIDLISTENERTHREAD__RUN,  line 1101 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdCustomTCPServer.pas
  $007AB880  TIDTHREAD__EXECUTE,  line 435 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdThread.pas
Call trace for block $74057080 size 27
  $002B4224
  $005EC968  INDYFORMAT,  line 7716 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/System/IdGlobal.pas
  $007ACC7C  TIDSCHEDULEROFTHREAD__NEWTHREAD,  line 200 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThread.pas
  $007ADAA4  TIDSCHEDULEROFTHREADDEFAULT__NEWTHREAD,  line 137 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThreadDefault.pas
  $007AD8F8  TIDSCHEDULEROFTHREADDEFAULT__ACQUIREYARN,  line 91 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThreadDefault.pas
  $00782FF0  TIDLISTENERTHREAD__RUN,  line 1101 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdCustomTCPServer.pas
  $007AB880  TIDTHREAD__EXECUTE,  line 435 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdThread.pas
Call trace for block $74482B80 size 22
  $00071C08  TAPPLICATION__GETTITLE,  line 1173 of ./include/application.inc
  $00072EB8  TAPPLICATION__SHOWEXCEPTION,  line 1592 of ./include/application.inc
  $00071ECC  TAPPLICATION__HANDLEEXCEPTION,  line 1261 of ./include/application.inc
  $0051CD58  DELIVERMESSAGE,  line 116 of lclmessageglue.pas
  $00419AD4  DELIVERMESSAGE,  line 3780 of ./gtk2/gtk2proc.inc
  $004291E4  DELIVERMOUSEUPMESSAGE,  line 2209 of ./gtk2/gtk2callback.inc
  $004293F8  GTKMOUSEBTNRELEASE,  line 2286 of ./gtk2/gtk2callback.inc
  $000CE5EC  TDOMSRV_FOR__OUVRIR_SITE_DOMO_DEFAUT,  line 2656 of umainsrvlaz.pas
  $000C7C78  TDOMSRV_FOR__FORMACTIVATE,  line 852 of umainsrvlaz.pas
  $00063F94  TCUSTOMFORM__ACTIVATE,  line 680 of ./include/customform.inc
  $000644F4  TCUSTOMFORM__CMACTIVATE,  line 842 of ./include/customform.inc
Call trace for block $751279E0 size 110
  $000B8188  SCHEDULETHREAD,  line 469 of /home/pi/dev/domsrvcliv15/communs/uschedulethread.pas
  $000C823C  TDOMSRV_FOR__FORMCREATE,  line 995 of umainsrvlaz.pas
  $00064910  TCUSTOMFORM__DOCREATE,  line 939 of ./include/customform.inc
  $00062778  TCUSTOMFORM__AFTERCONSTRUCTION,  line 149 of ./include/customform.inc
  $0006AC3C  TFORM__CREATE,  line 3184 of ./include/customform.inc
  $00074900  TAPPLICATION__CREATEFORM,  line 2239 of ./include/application.inc
  $0002621C  main,  line 65 of domsrvlaz.lpr
  $0002621C  main,  line 65 of domsrvlaz.lpr
  $005C5F14  TDTMPARSER__LOADXMLINOBJECT,  line 2512 of /home/pi/dev/domsrvcliv15/communs/uparser.pas
  $005C5F14  TDTMPARSER__LOADXMLINOBJECT,  line 2512 of /home/pi/dev/domsrvcliv15/communs/uparser.pas
  $0013228C  ODOMO__DOMO_CHARGER_FICHIERXML_DANS_DOMO,  line 26143 of /home/pi/dev/domsrvcliv15/communs/Domo.pas
  $00133438  ODOMO__DOMO_CHARGER_FICHIERXML,  line 26535 of /home/pi/dev/domsrvcliv15/communs/Domo.pas
  $005BD238  OSITES__OSITES_TSITE_SET,  line 776 of /home/pi/dev/domsrvcliv15/communs/uosites.pas
  $000C8128  TDOMSRV_FOR__FORMCREATE,  line 963 of umainsrvlaz.pas
  $00064910  TCUSTOMFORM__DOCREATE,  line 939 of ./include/customform.inc
  $00062778  TCUSTOMFORM__AFTERCONSTRUCTION,  line 149 of ./include/customform.inc
Call trace for block $75186D70 size 31
  $00072D88  TAPPLICATION__SHOWEXCEPTION,  line 1579 of ./include/application.inc
  $00071ECC  TAPPLICATION__HANDLEEXCEPTION,  line 1261 of ./include/application.inc
  $0051CD58  DELIVERMESSAGE,  line 116 of lclmessageglue.pas
  $00419AD4  DELIVERMESSAGE,  line 3780 of ./gtk2/gtk2proc.inc
  $004291E4  DELIVERMOUSEUPMESSAGE,  line 2209 of ./gtk2/gtk2callback.inc
  $004293F8  GTKMOUSEBTNRELEASE,  line 2286 of ./gtk2/gtk2callback.inc
  $0006AC3C  TFORM__CREATE,  line 3184 of ./include/customform.inc
  $00074900  TAPPLICATION__CREATEFORM,  line 2239 of ./include/application.inc
  $0002621C  main,  line 65 of domsrvlaz.lpr
  $0002621C  main,  line 65 of domsrvlaz.lpr
  $0002621C  main,  line 65 of domsrvlaz.lpr
  $0002621C  main,  line 65 of domsrvlaz.lpr
Call trace for block $75137CB0 size 64
  $00044E44
  $00048B88
  $007AD9C0  TIDSCHEDULEROFTHREADDEFAULT__RELEASEYARN,  line 106 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThreadDefault.pas
  $007AD120  TIDYARNOFTHREAD__DESTROY,  line 262 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThread.pas
  $000436C0
  $007ACEB0  TIDSCHEDULEROFTHREAD__TERMINATEYARN,  line 235 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThread.pas
  $007AD3B4  TIDSCHEDULER__TERMINATEALLYARNS,  line 184 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdScheduler.pas
  $007ACA50  TIDSCHEDULEROFTHREAD__DESTROY,  line 181 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdSchedulerOfThread.pas
  $00296368
  $007812F4  TIDCUSTOMTCPSERVER__DESTROY,  line 464 of /home/pi/outils/fpc/fpc320laz2012/lazarus/components/Indy-master/Lib/Core/IdCustomTCPServer.pas
  $000436C0
  $000B4598  RESEAU_DESTROY,  line 204 of /home/pi/dev/domsrvcliv15/communs/reseau.pas
  $000C875C  TDOMSRV_FOR__FORMCLOSEQUERY,  line 1086 of umainsrvlaz.pas
  $0006858C  TCUSTOMFORM__CLOSEQUERY,  line 2268 of ./include/customform.inc
  $00068330  TCUSTOMFORM__CLOSE,  line 2178 of ./include/customform.inc
  $000C9284  TDOMSRV_FOR__BTN_QUITTERCLICK,  line 1307 of umainsrvlaz.pas
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
//=======================================
Extrait code SERVEUR
//=======================================
//SERVER
unit utdtmreseauw;

{$IFDEF FPC}
{$mode objfpc}{$H+}
//{$Mode Delphi}
{$ENDIF FPC}


interface
uses
    Classes, SysUtils,

    //
    IdContext,
    IdTCPConnection,
    IdBaseComponent,
    IdComponent,
    IdSync,       //TIdNotify
    IdExceptionCore, //Acces Exceptions INDY
    IdException,
    IdStack,         //Exception EIdNotASocket
    IdCustomTCPServer,
    IdTCPServer,
    IdTCPClient,
    IdGlobal,   //TIdBytes
    IdYarn,    
........
type
  TDTMReseauW = class(TObject)  //datamodule commun Client et serveur
   private
   { private declarations }
     FTProc_TResEvent       :TProc_TResEvent;   //Proc Event Exec dans form appelante
     FTProc_Message         :TProc_Message;       //Proc Affichier Message dans form appelante
     FEstSrv                :boolean;
     FServer                :TIdTcpServer;        //Server
     FClient                :TIdTcpClient;        //Client
     FTClientThread         :TClientThread;       //CLIENT Thread Reception (en Var gene ???)
     //FTtab_TClientContext   :tab_TClientContext;  //TABLEAU d'ETAT des CONTEXT
     FCliTCliReseau         :TCliReseau;          //Context du client cote client
     FCLiOtherCli           :Tstrings;            //cote CLI:Liste des clients connectes
     FConnectTimeout        :longint;             //Temps de Connexion maxi d'un client
     FReadTimeout           :longint;             //Temps de lecture maxi d'un client
     FProgressMax           :integer;             //Avancement transfert:Voir event _clientwork,..
     FRes_Handle:THandle;          //Handle de la form qui va recevoir les events Reseau
     FRes_pmes:Tstrings;           //Pointeur vers une stringlist de la fanetre appelante(carte_for)

     //CARTES RESEAUX
     FDeviceList_Reseau_TCPIP:TStrings;           //Liste des devices de connexion de cartereseau
     FDeviceList_Reseau_TCPIP_Est_Connecte:boolean;
     FDeviceList_Reseau_TCPIP_NoEncours:integer;  //No Indice dans liste device carfte reaseau actif selectionne
     FDeviceList_Reseau_TCPIP_macadr:string;
     FDeviceList_Reseau_TCPIP_adrip:string;
   public
    constructor Create(VEstSrv:boolean;vprocmessage:TProc_Message;vprocevent:TProc_TResEvent);
    destructor Destroy; override;         
   ....
   end;
.........
procedure TDTMReseauW.Server_init;
begin
            if self.FServer<>nil then
            begin
                FServer.OnConnect     :={$IFDEF FPC}@{$ENDIF}_ServerConnect;
                FServer.OnDisconnect  :={$IFDEF FPC}@{$ENDIF}_ServerDisconnect;
                FServer.OnExecute     :={$IFDEF FPC}@{$ENDIF}_ServerExecute;
                FServer.OnException   :={$IFDEF FPC}@{$ENDIF}_ServerException;
                FServer.OnStatus      :={$IFDEF FPC}@{$ENDIF}_ServerStatus;
            end;
end;

procedure TDTMReseauW._ServerConnect(AContext: TIdContext);
var VSync:TMySync;
//Exec Session dans Main thread
    //Afficher message dans Main thread
  procedure Synchronize_message_afficher(s:string);
  begin
  Vsync := TMySync.Create;
          try
          VSync.FTSyncProcType:=syptMessage;
          Vsync.FString   := s;
          Vsync.Synchronize;
          finally
          Vsync.Free;
          end;
  end;
  procedure Synchronize_OnReseau_TraiterEvent_ServerConnect(VEstSrv:boolean;VTIdContext:TIdContext);
    begin
    Vsync := TMySync.Create;
            try
            Vsync.FEstSrv           :=VEstSrv;
            VSync.FTSyncProcType    :=syptEvent;
            VSync.FTSyncEventType   :=syetConnect;
            Vsync.FTIdContext       :=VTIdContext;
            //Vsync.FDataType    :=dtsession;
            //Vsync.FTSession    :=VTSession;
            Vsync.Synchronize;
            finally
            Vsync.Free;
            end;
    end;
begin
Synchronize_OnReseau_TraiterEvent_ServerConnect(true,AContext);
end;

//Traitement _ServerConnect:UNIQUEMENT MAJ Flag ETAT Context :
function TDTMReseauW.OnReseau_TraiterEvent_ServerConnect( VTIdContext:TIdContext):boolean;
var vmes:string;VTClientContext:TClientContext;
begin
result:=false;vmes:='Demande connexion Client ';
     if self<>nil then
     begin
          if VTIdContext=nil
          then vmes:=vmes+':ERR (Context=nil)'
          else
          begin
          VTClientContext:=TClientContext(VTIdContext);
          vmes:=vmes+' IP='+VTIdContext.Binding.PeerIP+'(port='+inttostr(VTIdContext.Binding.PeerPORT)+'):';
          //Flag CONNECT
                  if VTClientContext.CliReseau=nil
                  then vmes:=vmes+'(ERR:CliReseau=nil)'
                  else begin
                       if not VTClientContext.CliReseau.TCliReseau_Set_EtatConnect_Connect(VTIdContext.Binding.PeerIP)
                       then vmes:=vmes+'(ERR:Flag CONNECT)'
                       else begin
                       vmes:=vmes+'OK';
                       result:=true
                       end;
                  end;
          end;
     Reseau_Message(vmes,true);
     end
end;


procedure TDTMReseauW._ServerDisconnect(AContext: TIdContext);
var VSync:TMySync;
//Afficher message dans Main thread
  procedure Synchronize_message_afficher(s:string);
  begin
  Vsync := TMySync.Create;
          try
          VSync.FTSyncProcType:=syptMessage;
          Vsync.FString   := s;
          Vsync.Synchronize;
          finally
          Vsync.Free;
          end;
  end;

//Traiter Stream recu dans Main thread
  procedure Synchronize_ResEvent_CliDisconnect(vclilog,vcliip:string);
  begin
  Vsync := TMySync.Create;
          try
          vSync.FEstSrv              :=true;;
          VSync.FTSyncProcType       :=syptEvent;//syptMessageAttenteInit;
          Vsync.FTSyncEventType      :=syetDisconnect;
          Vsync.FCliDisconnectLog    :=vclilog;
          Vsync.FCliDisconnectIp     :=vcliip;
          //Vsync.FTStreamHeader  :=VTStreamHeader;
          Vsync.Synchronize;
          finally
          Vsync.Free;
          end;
  end;
var vip:string;
begin
vip:=AContext.Connection.Socket.Binding.PeerIP;
   if self.FServer<>nil then begin
      try
         try
         FServer.Contexts.LockList.Remove(AContext);//Blocage server
         except
         raise
         end;
      finally
      FServer.Contexts.UnlockList;
      end;
   end;
//ATTANTION: Plantage server si envoi simultane de message_afficher et reseventdisconnect: Soit l'un soit lautre
//Synchronize_message_afficher('Deconnexion Client IP='+vip);//AContext.Connection.Socket.Binding.PeerIP);
Synchronize_ResEvent_CliDisconnect('',vip);//AContext.Connection.Socket.Binding.PeerIP);
end;

procedure TDTMReseauW._ServerException(AContext: TIdContext;AException: Exception);
var VSync:TMySync;
//Afficher message dans Main thread
  procedure Synchronize_message_afficher(s:string);
  begin
  Vsync := TMySync.Create;
          try

          VSync.FTSyncProcType:=syptMessage;
          Vsync.FString   := s;
          Vsync.Synchronize;
          finally
          Vsync.Free;
          end;
  end;
var VAdripClient,vmes,VMsgPref:string;vnbcli:integer;
begin
     if AContext=nil
     then VMsgPref:='Event Exception (context=nil):'
     else
     begin
     VAdripClient:=AContext.Connection.Socket.Binding.PeerIP;
     VMsgPref:='Event Exception (client='+VAdripClient+'):';
     end;

     if AException.ClassType=EIdConnClosedGracefully then
     begin
     vmes:='CloseGracefully:'+ AException.Message;
     end;

     if AException.ClassType=EIdReadTimeout then
     begin
     vmes:=VMsgPref+'EIdReadTimeout:' + AException.Message;
     end
     else
      if AException.ClassType=EIdException then
      begin
      vmes:=VMsgPref+'EIdException :' + AException.Message;
      end
      else
      if AException.ClassType=Exception then
      begin
      vmes:=VMsgPref+'EXCEPTION :' + AException.Message;
      end
      else
      begin
      vmes:=VMsgPref+'EXCEPTION inconnue:' + AException.Message;
      end;

     AContext.Connection.IOHandler.WriteBufferClear;
     AContext.Connection.IOHandler.InputBuffer.Clear;
     AContext.Connection.IOHandler.CloseGracefully;
       if Acontext.Connection.connected
       then AContext.Connection.Disconnect;
        //if not self.Srv_Deconnecter_Client_SansAVIS(AContext) then;
Synchronize_message_afficher(vmes);
end;

procedure TDTMReseauW._ServerStatus(ASender: TObject;const AStatus: TIdStatus; const AStatusText: string);
var VSync:TMySync;
//Exec Session dans Main thread
  procedure Synchronize_OnReseau_TraiterEvent_ServerStatus(VEstSrv:boolean;VTIdContext:TIdContext;VTSyncEventStatus:TIdStatus);
    begin
    Vsync := TMySync.Create;
            try
            Vsync.FEstSrv           :=VEstSrv;
            VSync.FTSyncProcType    :=syptEvent;
            VSync.FTSyncEventType   :=syetStatus;
            VSync.FTSyncEventStatus :=VTSyncEventStatus;
            Vsync.FTIdContext       :=VTIdContext;
            //Vsync.FDataType    :=dtsession;
            //Vsync.FTSession    :=VTSession;
            Vsync.Synchronize;
            finally
            Vsync.Free;
            end;
    end;
begin
Synchronize_OnReseau_TraiterEvent_ServerStatus(true,TIdContext(ASender),AStatus);
end;



//Traitement _ServerSTatus:
function TDTMReseauW.OnReseau_TraiterEvent_ServerStatus( VTIdContext:TIdContext;VTSyncEventStatus:TIdStatus):boolean;
var vmes,vmestmp:string;
    VTClientContext:TClientContext;
    Vnbcli:integer;
begin
result:=false;vmes:='En connexion Client ';vmestmp:='';
     if self<>nil then
     begin
          if VTIdContext=nil
          then vmes:=vmes+':ERR (Context=nil)'
          else
          begin
              case VTSyncEventStatus of
                   hsConnecting:begin
                   //MAJ Readtimeout avant connexion
                   VTIdContext.Connection.IOHandler.ReadTimeout:=self.FReadTimeout;
                   vmes:=vmes+':OK (Readtimeout='+inttostr(FReadTimeout)+')';
                   end;
                   //..si besoin
              end;
          Reseau_Message(vmes);
          end;
     end
end;

//Traitement _ServerSTatus:
function TDTMReseauW.OnReseau_TraiterEvent_ClientStatus( VTSyncEventStatus:TIdStatus):boolean;
var vmes,vmestmp:string;
    VTClientContext:TClientContext;
    Vnbcli:integer;
begin
result:=false;vmes:='Status connexion Client ';vmestmp:='';
     if self<>nil then
     begin
              case VTSyncEventStatus of
                   hsDisconnected:begin
                   //ENVOI EVENT Form appelante pour MajBouton
                   self.Reseau_Message_Event_retMat(renDisconnect);
                   end;
                   //..si besoin
              end;
     end
end;

procedure TDTMReseauW._ServerExecute(AContext: TIdContext);
var VSync:TMySync;
//Afficher message dans Main thread
  procedure Synchronize_message_afficher(s:string);
  begin
  Vsync := TMySync.Create;
          try

          VSync.FTSYncProcType:=syptMessage;
          Vsync.FString   := s;
          Vsync.Synchronize;
          finally
          Vsync.Free;
          end;
  end;
//Exec Session dans Main thread
  procedure Synchronize_OnReseau_TraiterRequete_Session(VEstSrv:boolean;VTIdContext:TIdContext;VTSession:TSession);
    begin
    Vsync := TMySync.Create;
            try
            Vsync.FEstSrv           :=VEstSrv;
            VSync.FTSyncProcType    :=syptRequete;
            Vsync.FTIdContext       :=VTIdContext;
            Vsync.FDataType         :=dtsession;
            Vsync.FTSession         :=VTSession;
            Vsync.Synchronize;
            finally
            Vsync.Free;
            end;
    end;
//
//Exec TRequetdans Main thread
  procedure Synchronize_OnReseau_TraiterRequete_Requet(VEstSrv:boolean;VTIdContext:TIdContext;VTRequet:TRequet);
    begin
    Vsync := TMySync.Create;
            try
            Vsync.FEstSrv           :=VEstSrv;
            VSync.FTSyncProcType    :=syptRequete;
            Vsync.FTIdContext       :=VTIdContext;
            Vsync.FDataType         :=dtRequet;
            Vsync.FTRequet          :=VTRequet;
            Vsync.Synchronize;
            finally
            Vsync.Free;
            end;
    end;

//
//Exec TStreamHeader dans Main thread
  procedure Synchronize_OnReseau_TraiterRequete_Stream(VEstSrv:boolean;VTIdContext:TIdContext;VTStreamHeader:TStreamHeader);
    begin
    Vsync := TMySync.Create;
            try
            Vsync.FEstSrv           :=VEstSrv;
            VSync.FTSyncProcType    :=syptRequete;
            Vsync.FTIdContext       :=VTIdContext;
            Vsync.FDataType         :=dtStream;
            Vsync.FTStreamHeader    :=VTStreamHeader;
            Vsync.Synchronize;
            finally
            Vsync.Free;
            end;
    end;
var
  VTSession         :TSession;
  VTRequet          :TRequet;
  VTStreamHeader    :TStreamHeader;
  VTMemoryStream    :TMemoryStream;
  VNomficSauver     :string;
  // temporary buffer
  LBuffer: TBytes;
  // temporary message buffer
  LMessageBuffer: TBytes;
  // data size in InputBuffer
  LDataSize: Integer;
  // protocol structure
  LProtocol: TProtocol;
  // we need to HARD CAST AContext to TClientContext
  // in order to access our custom methods(procedures)
  LClientContext: TClientContext;
  VCtrlCleSession_OK:boolean;
  VEtatConnect_Connect_mes:string;
  vmes,vmestmp:string;
begin
  try
    if AContext.Connection.Connected then
    begin
         if not AContext.Connection.IoHandler.Connected
         then begin
         //LClientContext.Connection.Disconnect;
         //Synchronize_message_afficher('IdTCPServerExecute:ERR (not AContext.Connection.IoHandler.Connected)');
         //Exit;
         end
         else
         begin
         // hard cast AContext to TClientContext
         LClientContext := TClientContext(AContext);

          try
            //  if LClientContext.Connection.IOHandler.InputBufferIsEmpty then
            //begin
            //LClientContext.Connection.IOHandler.CheckForDataOnSource(FReadTimeout);
            //LClientContext.Connection.IOHandler.CheckForDisconnect(True);
            //    if LClientContext.Connection.IOHandler.InputBufferIsEmpty then Exit;
            //end;

          // store the size of the InputBuffer of the client
          LDataSize := LClientContext.Connection.IOHandler.InputBuffer.Size;
          // in order to prevent spams or to make sure that we have at least
          // the protocol structure sent we check the size of the InputBuffer
           if LDataSize < szProtocol
           then begin
           //Synchronize_message_afficher('serverexexute:recu taille='+inttostr(LDataSize));
           //LClientContext.Connection.IOHandler.InputBuffer.Clear;
           //LClientContext.Connection.IOHandler.CloseGracefully;
           //LClientContext.Connection.Disconnect;
           end
           else
           //if LDataSize >= szProtocol then
           begin

                try

                //Init Buffer
                ClearBuffer(TIdbytes(LBuffer));
                // read the protocol structure from the client so we can handle
                // the client's request
                  try
                  LClientContext.Connection.IOHandler.ReadBytes(TIdbytes(LBuffer), szProtocol);
                  except
                  LClientContext.Connection.Disconnect;
                  Exit;
                  end;
                //AddFmtLog('Readbytes long=%d', [length(LBuffer)]);
                // convert the buffer to protocol structure
                LProtocol := BytesToTProtocol(TIdBytes(LBuffer));
                //Ctrl Cle de session
                VCtrlCleSession_OK:=false;
                  if LClientContext.CliReseau=nil
                  then Synchronize_message_afficher('IdTCPServerExecute:ERR (CliReseau=nil)')
                  else
                  begin
                  VEtatConnect_Connect_mes:='';
                  //Soit Client en ETat Connect (pas encore de cle de session , soit Egalite cle de session
                     if LClientContext.CliReseau.TCliReseau_Est_EtatConnect_Connect
                     then begin
                     VCtrlCleSession_OK:=true;
                     VEtatConnect_Connect_mes:='Etatconnect='+inttostr(ord(LClientContext.CliReseau.TCliReseau_Est_EtatConnect_Connect));
                     end
                     else begin
                     VEtatConnect_Connect_mes:='Non Etatconnect='+inttostr(ord(LClientContext.CliReseau.TCliReseau_Est_EtatConnect_Connect));
                     VCtrlCleSession_OK:=(RCleSession_GetStr(LProtocol.FCleSession)=LClientContext.CliReseau.TCliReseau_Get_CleSessionStr);
                     end;
                  //VCtrlCleSession_OK:= LClientContext.CliReseau.TCliReseau_Est_EtatConnect_Connect or
                  //                     (RCleSession_GetStr(LProtocol.FCleSession)=LClientContext.CliReseau.TCliReseau_Get_CleSessionStr);
                     if not VCtrlCleSession_OK
                     then begin
                     Synchronize_message_afficher( 'IdTCPServerExecute:ERR (Cle de session)'+
                                       '(ip:'+LClientContext.Binding.PeerIP+' Log:'+LClientContext.CliReseau.TCliReseau_Get_LogStr+')'+
                                       '(EtatConnect='+VEtatConnect_Connect_mes+')'+
                                       '(CleSession recu='+RCleSession_GetStr(LProtocol.FCleSession)+')'+
                                       '(CleSession Context='+LClientContext.CliReseau.TCliReseau_Get_CleSessionStr+')');
                     end
                     else
                     begin
                        case LProtocol.FDataTypes of  //(dtindef,dtString, dtSession, dtSite, dtStream);
                        //==============================================
                        //SESSION
                          dtSession:begin
                          vmes:='ServerExecute(dtsession):';vmestmp:='';
                          Tsession_init(VTSession);
                            if not LProtocol.FDataSize=szTSession
                            then vmestmp:='ERR long Tsession Readbytes long'//AddFmtLog('ERR long Tsession Readbytes long datasize/session=%d', [LProtocol.FDataSize,szTSession])
                            else begin
                            //Lire les X bytes du record TSession
                               try
                               LClientContext.Connection.IOHandler.ReadBytes(TIdbytes(LBuffer), LProtocol.FDataSize);
                               except
                               LClientContext.Connection.Disconnect;
                               Exit;
                               end;
                            //Init Buffer
                            ClearBuffer(TIdbytes(LMessageBuffer));
                            //set the length of the temporary Session buffer
                            SetLength(LMessageBuffer, LProtocol.FDataSize);
                            // move the message data from the buffer to message buffer
                            Move(LBuffer[szProtocol], LMessageBuffer[0], LProtocol.FDataSize);
                            //AddFmtLog('Readbytes long=%d', [length(LMessageBuffer)]);
                            // convert the buffer to protocol structure
                              if not TSession_ByteArrayToRecord(LMessageBuffer,VTSession) //VTSession := BytesToTSession(LBuffer);
                              then vmestmp:='ERR Lecture Tsession' //Message_afficher('ServerExecute :ERR Lecture Tsession')
                              else begin
                              //Traiter requete
                              //Synchronize_message_afficher('Session Log/Mp='+TSession_Get_Log(VTSession)+TSession_Get_Mp(VTSession));
                              Synchronize_OnReseau_TraiterRequete_Session(true,AContext,VTSession);
                              end;
                            //..
                            end;
                            if vmestmp<>'' then Synchronize_message_afficher(vmes+vmestmp);
                          end;
                          //==============================================
                          //REQUET
                          dtRequet:begin
                          vmes:='ServerExecute(dtRequet):';vmestmp:='';
                          TRequet_init(VTRequet);
                            if not LProtocol.FDataSize=szTRequet
                            then vmestmp:='ERR long TRequet Readbytes long'//AddFmtLog('ERR long Tsession Readbytes long datasize/session=%d', [LProtocol.FDataSize,szTSession])
                            else begin
                            //Lire les X bytes du record TSession
                            LClientContext.Connection.IOHandler.ReadBytes(TIdbytes(LBuffer), LProtocol.FDataSize);
                            //Init Buffer
                            ClearBuffer(TIdbytes(LMessageBuffer));
                            //set the length of the temporary Session buffer
                            SetLength(LMessageBuffer, LProtocol.FDataSize);
                            // move the message data from the buffer to message buffer
                            Move(LBuffer[szProtocol], LMessageBuffer[0], LProtocol.FDataSize);
                            //AddFmtLog('Readbytes long=%d', [length(LMessageBuffer)]);
                            // convert the buffer to protocol structure
                              if not TRequet_ByteArrayToRecord(LMessageBuffer,VTRequet) //VTRequet := BytesToTSession(LBuffer);
                              then vmestmp:='ERR Lecture TRequet' //Message_afficher('ServerExecute :ERR Lecture Tsession')
                              else begin
                              //Traiter requete
                              //Synchronize_message_afficher('Session Log/Mp='+TSession_Get_Log(VTSession)+TSession_Get_Mp(VTSession));
                              Synchronize_OnReseau_TraiterRequete_Requet(true,AContext,VTRequet);
                              end;
                            //..
                            end;
                            if vmestmp<>'' then Synchronize_message_afficher(vmes+vmestmp);
                          end;
                          dtStream:begin
                            vmes:='';
                            TStreamHeader_init(VTStreamHeader);
                              if not LProtocol.FDataSize=szTStreamHeader
                              then Synchronize_message_afficher(format('ERR long TStreamHeader Readbytes long datasize/Requet=%d', [LProtocol.FDataSize,szTStreamHeader]))
                              else begin
                              //Lire les X bytes du record TRequet
                              LClientContext.Connection.IOHandler.ReadBytes(TIdbytes(LBuffer), LProtocol.FDataSize);
                              //FTCPClient.IOHandler.ReadBytes(LBuffer, LProtocol.FDataSize);
                              //Effacer LMessage
                              ClearBuffer(TIdbytes(LMessageBuffer));
                              //set the length of the temporary Requet buffer
                              SetLength(LMessageBuffer, LProtocol.FDataSize);
                              // move the message data from the buffer to message buffer
                              Move(LBuffer[szProtocol], LMessageBuffer[0], LProtocol.FDataSize);
                              //Synchronize_message_afficher(format('Readbytes long=%d', [length(LMessage)]));
                              // convert the buffer to protocol structure
                                 if not TStreamHeader_ByteArrayToRecord(LMessageBuffer,VTStreamHeader) //VTRequet := BytesToTRequet(LBuffer);
                                 then Synchronize_message_afficher('TClientThread.Execute :ERR Lecture TStreamHeader')
                                 else begin
                                 //Lire Stre
                                 vmes:=vmes+'OK NomFichier:'+VTStreamHeader.FileName+
                                  ' Path: '+VTStreamHeader.FilePath+
                                  ' Taille: '+IntToStr(VTStreamHeader.FileSize);
                                 VTMemoryStream:=TMemoryStream.Create;
                                   try
                                   LClientContext.Connection.IOHandler.ReadStream(VTMemoryStream, VTStreamHeader.FileSize);
                                   //Traiter Fichier:
                                   //1)Stocker dans rep TMP
                                   //2)DoOnReseau_TraiterRequete_Stream s'occupe de deplacer fichier et renommer au bon endroit
                                   //ex:Sauver dans autre nom
                                   VNomficSauver:=Fichier_FormateNomComplet_FichierTmp(TStreamHeader_Get_Filenamestr(VTStreamHeader));//VTStreamHeader.FileName);
                                   //VNomficSauver:='rec_'+FTStreamHeader.FileName;
                                        if fileexists(VNomficSauver)
                                        then SysUtils.deletefile(VNomficSauver);
                                   VTMemoryStream.SaveToFile(VNomficSauver);
                                   String_Concatener_SLINEBREAK(vmes,' Sauvegarde "'+VNomficSauver+'"');
                                   finally
                                   Freeandnil(VTMemoryStream);
                                   end;
                                 //Traiter requete
                                 Synchronize_message_afficher('_ServerExecute :'+vmes);
                                 Synchronize_message_afficher('_ServerExecute :DoOnReseau_TraiterRequete_Stream');
                                 //V51:DoOnReseau_TraiterRequete_Stream;
                                 Synchronize_OnReseau_TraiterRequete_Stream(true,AContext,VTStreamHeader);
                                 end;
                              end;
                          end
                          else vmes:='ServerExecute Type FDataTypes inconnu';
                        end;    //END Case
                     end
                  end;
                finally
                ClearBuffer(TIdbytes(LBuffer));
                ClearBuffer(TIdbytes(LMessageBuffer));
                end; // tryf
           end;
          finally

          end;

         end
    end
  except
        on E:EIdConnClosedGracefully do begin
        vmes:='IdTCPServerExecute EXCEPTION CloseGracefully:'+E.Message+' client';
        raise
        end;
        //on E:EIdConnectTimeout do begin  NE MARCHE PAS cote serveur
        on E:EIdReadTimeout do begin
        vmes:='IdTCPServerExecute EXCEPTION READTIMEOUT:'+E.Message+' client';
        raise
        end;
        on E:EIdException do begin
        vmes:='IdTCPServerExecute EXCEPTION EIdException:'+E.Message+' client';
        raise
        end;
        on E:Exception do begin
        vmes:='IdTCPServerExecute EXCEPTION:'+E.Message+' client';
        raise
        end
        else begin
        vmes:='IdTCPServerExecute EXCEPTION:inconnue';
        raise
        end;
  end;

end;  
 
destructor  TDTMReseauW.Destroy;
var vmes:string;
begin
       if FEstSrv then
       begin
            if Srv_Deconnecter(vmes) then;
       Reseau_message(vmes);
       FreeandNil(FServer);
       end
       else begin
            if cli_deconnecter(true,vmes) then ;
       Reseau_message(vmes);
       //Forcer terminate CLientThread:
       //(IMPORTANT car cli_deconnecter ne fait pas le terminate c'est le disconnect qui declenche uniquement
            if FTClientThread<>nil
            then begin
            //terminate the listener thread
            FTClientThread.Terminate;
            FTClientThread.waitfor;//eviter car en lock clientthread
            FreeAndNil(FTClientThread);
            end;
            if FCliTCliReseau<>nil
            then begin
            //FreeandNil(FCliTCliReseau);
            FCliTCliReseau.destroy;
            FCliTCliReseau:=nil;
            end;
            if FCLiOtherCli<>nil
            then FreeandNil(FCLiOtherCli);
            if FClient<>nil
            then FreeandNil(FClient);
       end;

//Liste des cartes reseau
    if FDeviceList_Reseau_TCPIP<>nil
       then FDeviceList_Reseau_TCPIP.Free;

inherited destroy
end;      
//Connecter Serveur: AdrIP ,PortReseau et Timeout
function TDTMReseauW.Srv_Connecter(VadripSrv:string;vPortReseau:string;VReadtimeout:string;var vmes:string):boolean;
var VPortint:integer;VReadTimeoutint:int64;//longint;
begin
result:=false;vmes:='Connexion Serveur ';
  if self<>nil then
  begin
        if Srv_est_connecte
        then vmes:= vmes+':WAR (Serveur deja connecte)'
        else
        begin
           if VadripSrv=''
           then vmes:=vmes+':ERR (AdrIP vide)'
           else begin
           vmes:=vmes+'AdrIP='+VadripSrv;
              if not trystrtoint(vPortReseau,VPortint)
              then vmes:=vmes+':ERR (Port incorrect)'
              else begin
              vmes:=vmes+' Port='+vPortReseau;
                if not trystrtoint64(VReadTimeout,VReadTimeoutint)
                then vmes:=vmes+':ERR (Readtimeout incorrect)'
                else begin
                vmes:=vmes+' Timeout='+VReadTimeout+':';
                     try
                     FReadTimeout:=VReadTimeoutint; //Memoriser pour etre utilise a chaque connect d'un client
                     FServer.MaxConnections:=3;
                     FServer.Bindings.Clear;
                        with FServer.Bindings.Add do
                        begin
                        IPVersion     :=Id_IPv4;
                        IP            :=VadripSrv;// '127.0.0.1';
                        Port          :=strtoint(vPortReseau);
                        end;
                     //vmes:= vmes+'IP='+FServer.Bindings.Items[0].IP+' PORT='+inttostr(FServer.Bindings.Items[0].Port);
                     FServer.active       :=true;
                     result:=true;
                     vmes:= vmes+':OK';
                     except
                       on E: EIdException do begin
                       vmes:=vmes+'ERR ' + E.Message;
                       end;
                       on E: Exception do begin
                       vmes:=vmes+'ERR ' + E.Message;
                       end
                       else
                       vmes:=vmes+'Srv_Connecter:EXCEPTION'
                     end;
                end
              end
           end;
        end;
   end
end;  

function TDTMReseauW.Srv_Deconnecter(var vmes:string):boolean;
var vmestmp:string;
begin
result:=false;vmes:='Deconnexion Serveur:';
  if self<>nil then
  begin
       try
       //Deconnecter les clients AVEC envoi requet AVIS
           if not Srv_Deconnecter_Clients('ARRET Serveur',vmestmp)
           then vmes:=vmes+':WAR '+vmestmp
           else vmes:=vmes+':OK '+vmestmp;
       //Deconnecter Server
         if Srv_est_connecte
         then
         begin
         //sleep(1000);
         //FServer.Scheduler.TerminateAllYarns;
         FServer.active:=false;

         end;
       vmes:=vmes+'/Arret Serveur:OK';
       except
                 on E: EIdException do begin
                       vmes:=vmes+'ERR ' + E.Message;
                       end;
                 on E: Exception do begin
                       vmes:=vmes+'ERR ' + E.Message;
                       end;
                 on E: EIdNotASocket do begin
                       vmes:=vmes+'ERR ' + E.Message;
                       end;
                 on E: EIdSocketError do begin
                       vmes:=vmes+'ERR ' + E.Message;
                       end;
                 else  begin
                       vmes:=vmes+'EXCEPTION ';
                       end;
       raise
       end;
  result:=true;
  end;
end;   


//SERVEUR:Deconnecter tous les clients
function TDTMReseauW.Srv_Deconnecter_Clients(vcomment:string;var vmes:string):boolean;
var i:integer;VTClientContext:TClientContext;
  // client list, holds TClientContext objects
  LClients: TList;//Voir http://stackoverflow.com/questions/32722256/delphi-android-app-indy-tcp-server-application-closes-after-client-disconnect

  VNBcli:integer;
  VadrIp,vmestmp:string;
  VStop,Vtrouve:boolean;
begin
result:=false;vmes:='Deconnecter Clients';vmestmp:='';VNBcli:=0;
     if self<>nil then
     begin
       //ENVOIS AVIS
       VStop:=false;
            while not VStop do begin   //On boucle pour Maj CLient Non Disconnecting: ca a lair de marcher
            vtrouve  :=false;
              if FServer=nil
              then VStop:=true
              else begin
              //Locker Liste
                with FServer.Contexts.LockList do begin
                 try
                     try
                     String_Concatener_SLINEBREAK(vmes,'-Nbre Envoi Avis='+inttostr(Count)+':');
                        for i:=0 to Count-1 do // length(TTab_TClientContext)-1 do
                        begin
                        VTClientContext:=TClientContext(items[i]);
                          if not VTClientContext.CliReseau.TCliReseau_Est_EtatConnect_Disconnecting then
                          begin
                          vtrouve:=true;
                          VTClientContext.Lock;
                          VadrIp:=VTClientContext.TClientContext_Get_AdrIp;
                             try
                                try
                                   if not OnReseau_Srv_sendTSession_CliClose(VTClientContext,Vcomment,vmestmp)
                                   //if not Reseau_Srv_ReseauClient_send_DeconnecterCli(VTClientContext,Vcomment,vmestmp)
                                   then String_Concatener_SLINEBREAK(vmes,' -Client  IP='+VadrIp+':AVIS Close:ERR'+':'+vmestmp)
                                   else String_Concatener_SLINEBREAK(vmes,' -Client  IP='+VadrIp+':AVIS Close:OK');

                                except   //Pour unlock context
                                vmes:=vmes+'ERR:ENVOI AVIS a un client:'+VadrIp;
                                //On deconnecte le Context
                                VTClientContext.Connection.IOHandler.WriteBufferclear;
                                VTClientContext.Connection.IOHandler.InputBuffer.clear;
                                //VTClientContext.Connection.IOHandler.Close;
                                VTClientContext.Connection.IOHandler.CloseGracefully;
                                //VTClientContext.Connection.DisconnectNotifyPeer;
                                    if VTClientContext.Connection.Connected
                                    then VTClientContext.Connection.Disconnect;
                                raise
                                end;
                             finally
                             //unlock
                             VTClientContext.Unlock;
                             end; // tryf
                          end;
                        end;

                     except
                           on E:exception do
                           logfile_ecrire(nil,'Srv_Deconnecter_Clients:Envoi avis:'+E.message)
                     end;

                   finally
                   //Delocker les contexts
                   FServer.Contexts.UnlockList;
                   end;
                 end;         //END WITH
                end;
                    if not Vtrouve then begin
                    VStop:=true;
                    end
            end;      //END WHILE
       //reseau_Message(vmes);
       sleep(1000);
       //=================================================================
       //DECONNEXIONS
       //VERSION"2"
         // lock the client list
          with FServer.Contexts.LockList do begin
          String_Concatener_SLINEBREAK(vmes,'-Nbre Deconnexion='+inttostr(count)+':');
               try
                  try
                  //DECONNEXION
                    for i:=count-1 downto 0 do
                    begin
                    VTClientContext:=TClientContext(items[I]);//DTMReseauW.TTab_TClientContext[i];
                       if VTClientContext<>nil then begin
                       //lock it
                       VTClientContext.Lock;
                       VadrIp:=VTClientContext.TClientContext_Get_AdrIp;
                         try
                            try
                            VTClientContext.Connection.IOHandler.WriteBufferclear;
                            VTClientContext.Connection.IOHandler.InputBuffer.clear;
                            //VTClientContext.Connection.IOHandler.Close;
                            VTClientContext.Connection.IOHandler.CloseGracefully;
                            //VTClientContext.Connection.DisconnectNotifyPeer;
                                if VTClientContext.Connection.Connected
                                then VTClientContext.Connection.Disconnect;

                            String_Concatener_SLINEBREAK(vmes,' -Client  IP='+VadrIp+':Deconnecter:OK');
                            except   //Pour unlock context
                            vmes:=vmes+'ERR:ENVOI AVIS a un client:'+VadrIp;
                            raise
                            end;
                         finally
                         //unlock
                         VTClientContext.Unlock;
                         end; // tryf
                       end;
                    end;
                  except
                  vmes:=vmes+'ERR:DECONNEXION des clients';
                  raise
                  end;
               finally
               //unlock client list
               FServer.Contexts.UnlockList;
               end; // tryf
               with FServer.Contexts.LockList do begin
               String_Concatener_SLINEBREAK(vmes,'-Nbre Deconnexion APRES='+inttostr(count)+':');
               FServer.Contexts.UnlockList;
               end;
          end; //END With

       //Message_afficher(vmes);
       result:=true;
       end;
end;