Bonjour à tous,

Afin que mon expérience serve à d'autres, si vous souhaitez utiliser un socket Client en mode non blocking avec reconnexion automatique voici l'algorithme à suivre :

Les étapes ci-dessous peuvent être réalisées avec un "case of" d'une fonction qui doit être appelée régulièrement par un timer ou un thread.

1) Etape de connexion:
Appeler Close; (nécessaire, plus tard, lors de la reconnexion mais ne pose pas de problème la première fois)
Appeler Open;
Initialiser un time out (avec GetTickcount par exemple)
Aller à l'étape suivante

2) Etape d'attente de connexion:
okSelect:=TCpClient1.Select(@bReadReady, @bWriteReady, @bExceptFlag); // toutes les variables sont des boolean
if okselect and bWriteReady and (TcpClient1.Active) then ==> aller à l'étape suivante
else ==> si un time out de 3 secondes est dépassé , retourner à l'étape 1 sinon rester à cette étape

3) Etape de communication
Pour envoyer une trame, appeller TcpClient1.SendBuf(TxData^,len);
Pour lire la réponse appeller: NbBytes:=TcpClient1.ReceiveBuf(RxData[0],RxDataSize);
Dans le même temps si on a reçu une erreur dans la fonction callback OnError qui est différente de 10035 alors aller à l'étape suivante sinon rester en permanence à cette étape.

4) Etape de reconnexion
Attendre un time out de 3 seconde et retourner à l'étape 1


J'ai testé cet algo dans le cas d'une déconnexion soft du serveur, d'une reconnexion, d'un débranchement de câble coté serveur et coté client, du rebranchement du câble. Ce composant ne consomme pas de "process handle" lorsque le serveur est déconnecté (contrairement au composant Tclientsocket) ni de mémoire. J'ai testé cet algo sur 24 heures avec serveur déconnecté et serveur connecté en permanence (en localhost et en distant) avec échange de trame toutes les 100ms environ et n'ai constaté aucun problème.

Petite remarque si votre application doit tourner plusieurs semaines sans rebouter le PC, si vous utilisez GetTickcount, il faut tenir compte du fait que ce compteur est remis à zéro tous les (49 ?) jours environs (dépassement de variable 32 bits). Donc passer par une fonction qui gère ce dépassement.

Autre remarque: si vous avez des périodes d'inactivité (pas d'échange de trame à réaliser avec le serveur) et si vous souhaitez quand même vérifier la présence du serveur (keepalive), dans ce cas il faut appeller la fonction n:=TcpClient1.ReceiveBuf(RxData[0],0); (avec longueur nulle). Si le serveur es présent, la valeur de retour doit être -1, mais si la valeur de retour est 0, alors il faut relancer le processus de connexion après un time out.

Si vous avez des questions, n'hésitez pas à me contacter.

Franck