Bonjour,
Je me tue à essayer de faire marcher un server TCP an mode stThreadBlocking et je n'arrive pas à détecter lorsque le client se déconnecte.
La propriété Connected est toujours à true.

Voilà mon code:

Création de l'objet serveur
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
    ServerSocket := TServerSocket.Create(self);
    ServerSocket.Port                := TcpPort;
    ServerSocket.Servertype       := stThreadBlocking;
    ServerSocket.OnThreadStart  := ServerThreadStart;
    ServerSocket.OnThreadEnd    := ServerThreadEnd;
    ServerSocket.OnGetThread         := ServerGetThread;
    ServerSocket.OnClientRead        := ServerSocket1ClientRead;
    ServerSocket.OnClientWrite       := ServerSocket1ClientWrite;
    ServerSocket.OnAccept            := ServerSocket1Accept;
    ServerSocket.OnClientConnect     := ServerSocket1ClientConnect;
    ServerSocket.OnClientDisconnect  := ServerSocket1ClientDisconnect;
    ServerSocket.OnListen            := ServerSocket1Listen;
    ServerSocket.OnClientError       := ServerSocket1ClientError;
Dans toutes les procédures ci-dessus je ne fais qu'afficher du texte dans un log sauf pour ServerGetThread

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
procedure TASCIIOneServer.ServerGetThread(Sender: TObject; ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread);
begin
  SocketThread := TServerThread.Create( FALSE, ClientSocket );
end;
Et dans le thread le code est le suivant
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
 
procedure TServerThread.ClientExecute;
Const
  REQUESTSIZE = 1000;
  CLIENTWAITTIME = 1000;
Var
  len : integer;
  fRequest : TByteArray;
begin
  inherited FreeOnTerminate := TRUE;
  try
    fSocketStream := TWinSocketStream.Create( ClientSocket, CLIENTWAITTIME ); // timeout de 1 seconde
    try
      len := 0;
      FillChar( fRequest, REQUESTSIZE, 0 );
      while (not Terminated) and (ClientSocket.Connected) do
      Begin
        len := fSocketStream.Read( fRequest[0], REQUESTSIZE );
        while len=REQUESTSIZE do len := fSocketStream.Read( fRequest[0], REQUESTSIZE ); // empty the input buffer
        if len>0 then  fSocketStream.Write( fRequest, len); // echo
        sleep(10);
      End;
      ClientSocket.Close;
    finally
      fSocketStream.Free;
    end;
  except on e:exception do
    begin
      // An error has occurred, close and exit
      ClientSocket.Close;
      Terminate;
    end;
  end;
end;
Dans le code ci-dessus, lorsque le client se ferme, ClientSocket.Connected est toujours true et lorsqu'il se reconnecte, un nouveau thread est créé et le compteur de nombre de clients est incrémenté.

Qu'y a-t-il dans ce code qui ne fonctionne pas ?
PS: Je n'ai pas utilisé la fonction WaitForData car cela provoque une exception lors de la destruction de l'objet ou lors de la fermeture de l'application si le temps paramétré n'est pas écoulé.
Je souhaiterai aussi resté connecté même s'il n'y a pas d'échanges.

Merci