PC SOFT

PROFESSIONAL NEWSGROUPS
WINDEVWEBDEV and WINDEV Mobile

Home → WINDEV 2024 → Reconnexion automatique.
Reconnexion automatique.
Started by Maxime, Jun., 19 2019 9:25 AM - 11 replies
Registered member
106 messages
Popularité : +1 (1 vote)
Posted on June, 19 2019 - 9:25 AM
Bonjour ,

Je possède le code suivant :

Procedure Connexion()

bConnecte est un booléen = Faux
TANTQUE PAS bConnecte
bConnecte = SocketConnecte("connexion",502,"***.***.***.***)
Multitâche(-1)
FIN

Socket.Option = SocketNagleOff
SI SocketChangeModeTransmission("connexion",SocketSansMarqueurFin)= Vrai ALORS
RENVOYER(Vrai)
SINON
RENVOYER(Faux)
FIN

Ce code est utilisé pour une procédure en Modbus tcp/ip.
Actuellement ce code essaye de ce reconnecté au lancement jusqu'à réussir mais j'ai besoin d’allée encore plus loin.
Je m'explique j'aimerai que ce code peut importe le moment essaye de ce reconnecté automatique si il ne l'ai pas ou plus.
Admettons on coupe l'alimentation de l'automate sans éteindre le service , dès que l'automate est alimenté le programme doit ce reconnecté sans interaction d'un utilisateur .

Cordialement
Message modified, June, 19 2019 - 9:25 AM
Registered member
106 messages
Popularité : +1 (1 vote)
Posted on June, 20 2019 - 11:53 AM
Bonjour ,

Quelqu'un aurai une solution a mon problème ?

Cordialement
Registered member
3,846 messages
Popularité : +227 (347 votes)
Posted on June, 20 2019 - 12:38 PM
Bonjour,
Pourquoi ne pas tester régulièrement la disponibilité de la connexion via une procédure automatique ? https://doc.pcsoft.fr/?9000072

--
Il y a peut être plus simple, mais, ça tourne
Registered member
106 messages
Popularité : +1 (1 vote)
Posted on June, 20 2019 - 12:52 PM
bonjour ,

Il me semble pas que je peux ouvrir plusieurs socket connecte avec le même nom .

Mon programme est une connexion entre un service et un automate .
Le socket existe même si la communication est rompu il existera toujours et rentrera en conflit tant qu'il n'est pas fermer
J'ai pensé à fermer à chaque fin de procédure automatique le socket et l'ouvrir au prochain appel ( toutes les 5 à 10 sec ) mais je pense que ça va surchargé le trafic réseau et je pense qu'il y a plus optimisé .


Cordialement
Registered member
106 messages
Popularité : +1 (1 vote)
Posted on June, 21 2019 - 12:36 PM
Bonjour ,

Quelqu'un aurai une idée optimisé a mon problème ?
Si on peux évité les socket ferme a chaque fois c'est préférable .
Merci


Cordialement Maxime
Registered member
2 messages
Posted on June, 21 2019 - 12:44 PM
bonjour ,
je suis débutant windev mais je vois que dans ton code il manque des guillemets
je dit peut être une bêtise mais :

Procedure Connexion()

bConnecte est un booléen = Faux
TANTQUE PAS bConnecte
bConnecte = SocketConnecte("connexion",502,"***.***.***.***) // tu met des guillemets avec le **** et tu ferme pas .....
Multitâche(-1)
FIN

Socket.Option = SocketNagleOff
SI SocketChangeModeTransmission("connexion",SocketSansMarqueurFin)= Vrai ALORS
RENVOYER(Vrai)
SINON
RENVOYER(Faux)
FIN
----------------------------------------
bConnecte = SocketConnecte("connexion",502,"***.***.***.***) // tu met des guillemets avec le **** et tu ferme pas .....

si je me trompe ne pas prendre en compte mon commentaire , :)

bon dev ludo

--
tout seul tu peut faire des choses, à plusieurs tu peut refaire le monde ....
Registered member
106 messages
Popularité : +1 (1 vote)
Posted on June, 21 2019 - 2:08 PM
Bonjour ,

C'est une erreur je l'ai supprimé sans le vouloir quand j'ai remplacé l'adresse IP par les " *** " .
Merci quand même.

Cordialement
Posted on June, 22 2019 - 7:52 AM
bonjour

voici le principe que j'utilise dans un executable pour communiquer avec un automate siemens en TCP dans un protocole spécifique développé sur mesure et jusqu'à maintenant (quelques mois) je n'ai pas eu de pb de deconnexion-reconnexion.


Procedure Automate_TCP_INIT()

// Connexion au serveur
RetK est un booléen
RetK=SocketConnecte(NomSocketS1,PortCnxS1,AdresseSiemens)
SI ErreurDétectée OR NOT RetK ALORS
// Erreur lors de la connexion
SocketS1_OK=Faux
ELSE
SocketChangeModeTransmission(NomSocketS1,SocketSansMarqueurFin)
FIN

// Execution du thread de réception des messages
IF ThreadEtat(NomThreadReceptionS1) = threadInexistant THEN
ThreadExecute(NomThreadReceptionS1,threadNormal,Automate_TCP_SOCKET_Reception)
END


Procedure Automate_TCP_SOCKET_Reception()

// Tant que le thread n'est pas arrêté, on attend des messages
BOUCLE
// Attente et lecture du prochain message
ERR_SOCK = Faux
QUAND EXCEPTIONEXCEPTION DANS
sMessage = SocketLit(NomSocketS1,Faux,600,4096)
FAIRE
ERR_SOCK = Vrai
FIN
IF sMessage="" AND ErreurDétectée THEN ERR_SOCK = Vrai
IF ERR_SOCK THEN
SI SocketExiste(NomSocketS1) ALORS
SocketFerme(NomSocketS1)
FIN
Automate_TCP_INIT()
END
IF sMessage<>"" THEN
// traitement analyse du contenu
END
//
ThreadPause(10) // centiemes seconde
FIN // boucle
Registered member
106 messages
Popularité : +1 (1 vote)
Posted on June, 26 2019 - 11:51 AM
Bonjour Fabien ,

Merci pour votre réponse mais y a des choses que je ne comprend pas dans vos fonctions .
SocketS1_OK , NomThreadReceptionS1 , sMessage , ERR_SOCK correspondent à quoi ? ( comment sont elles déclarées ?

Cordialement Maxime
Registered member
106 messages
Popularité : +1 (1 vote)
Posted on June, 27 2019 - 9:51 AM
Bonjour ,

Petit up

Merci
Registered member
106 messages
Popularité : +1 (1 vote)
Posted on July, 02 2019 - 3:00 PM
bonjour ,

up

Merci
Posted on July, 02 2019 - 6:55 PM
Bonjour,

J'ai déjà essayé de répondre à un autre post dans lequel la personne
n'arrivait pas à detecter la perte de la socket, à tester

J'imagine que tu as un socketlit quelque part et que l'automate parle
régulièrement donc tu définis une certaine limite, si au bout de ce
temps ton socketlit n'a rien renvoyé alors tu fermes la socket et
relance ta procédure de connexion

Je suis peut etre hors sujet mais ca peut aider, voici un code qui
permet de killer les sockets ouvertes sous windows et pas fermées
proprement en fonction d'une ip



// Utilisés par 'IpHlpApi.DLL'
// Structure pour récupérer les sockets ouverts
sMIB_TCPROW est une structure //typedef struct _MIB_TCPROW {
State est un entier sur 4 octets //DWORD dwState;
LocalAddr est un entier sur 4 octets //DWORD dwLocalAddr;
LocalPort est un entier sur 4 octets //DWORD dwLocalPort;
RemoteAddr est un entier sur 4 octets //DWORD dwRemoteAddr;
RemotePort est un entier sur 4 octets //DWORD dwRemotePort;
FIN //} MIB_TCPROW, *PMIB_TCPROW;

sMIB_TcpTable est une structure //typedef struct _MIB_TCPTABLE {
numEntries est un entier = 1 //DWORD dwNumEntries; //MIB_TCPROW
table[ANY_SIZE];
tabRes est un tableau fixe de 1000 sMIB_TCPROW
//Tabres est un entier sans signe sur 4 octets
FIN //} MIB_TCPTABLE, *PMIB_TCPTABLE;

// Structure pour récupérer les sockets ouverts avec le pid de
l'application
sMIB_TCPROW_OWNER_PID est une structure
State est un entier sur 4 octets
LocalAddr est un entier sur 4 octets
LocalPort est un entier sur 4 octets
RemoteAddr est un entier sur 4 octets
RemotePort est un entier sur 4 octets
OwningPid est un entier sur 4 octets
FIN

sMIB_TcpTableOwnerPid est une structure
numEntries est un entier = 0
tabRes est un tableau fixe de 1000 sMIB_TCPROW_OWNER_PID
FIN





PROCEDURE PRIVÉE WinSockFermeFromIp(Ip, Port = 0, Type="remote", Tracer
est booléen = Faux)
// Ferme une socket en fonction de l'IP distante
// Type : local ou remote
MIB_tcpTable est un sMIB_TcpTable
MIB_TCPROW est un sMIB_TCPROW
IpLocale est chaîne
PortLocal est entier
IpDistante est chaîne
PortDistant est entier
MessErr est chaîne

SI WinSockListe(MIB_tcpTable, MessErr) ALORS
POUR b=1 A MIB_tcpTable:numEntries
IpDistante = EntierVersIp(MIB_tcpTable:tabRes[b]:RemoteAddr)
PortDistant = inet_port(MIB_tcpTable:tabRes[b]:RemotePort)

IpLocale = EntierVersIp(MIB_tcpTable:tabRes[b]:LocalAddr)
PortLocal = inet_port(MIB_tcpTable:tabRes[b]:LocalPort)

SELON Type
CAS "remote"
SI Ip<>"" _ET_ IpDistante<>Ip ALORS CONTINUER
SI Port>0 _ET_ PortDistant<>Port ALORS CONTINUER
CAS "local"
SI Ip<>"" _ET_ IpLocale<>Ip ALORS CONTINUER
SI Port>0 _ET_ PortLocal<>Port ALORS CONTINUER
AUTRE CAS
CONTINUER
FIN

MIB_TCPROW = MIB_tcpTable:tabRes[b]

SI Tracer ALORS
WL.Trace("Tentative de fermeture socket de
"+IpLocale+":"+PortLocal+" <-> "+IpDistante+":"+PortDistant)
FIN

SI WinSockFerme(MIB_TCPROW,MessErr) ALORS
SI Tracer ALORS WL.Trace("Ok")
SINON
SI Tracer ALORS WL.Trace(MessErr)
FIN
FIN

RENVOYER Vrai
SINON
SI Tracer ALORS WL.Trace(MessErr)

RENVOYER Faux
FIN





PROCEDURE PRIVÉE WinSockFerme(MIB_TCPROW est un sMIB_TCPROW, MessErr
est chaîne = "")
// Ferme une socket
// MIB_TCP_STATE_DELETE_TCB=12 The TCP connection is in the delete TCB
state that represents the deletion of the Transmission Control Block
(TCB), a data structure used to maintain information on each TCP entry.

l_res est un entier
ValRetour est booléen = Faux

MIB_TCPROW:State=12

QUAND EXCEPTION DANS
l_res = API("IpHlpApi.DLL", "SetTcpEntry", &MIB_TCPROW)
FAIRE
MessErr=ExceptionInfo(errComplet)

GOTO FINPROG
FIN

SELON l_res
CAS 0
MessErr=""
ValRetour = Vrai
CAS -1
// Unsuccessful
MessErr="Unsuccessful"
CAS 65
// User has no sufficient privilege to execute this API successfully
MessErr="User has no sufficient privilege to execute this API
successfully"
CAS 87
// Specified port is not in state to be closed down
MessErr="Specified port is not in state to be closed down"
CAS 317
MessErr="The function is unable to set the TCP entry since the
application is running non-elevated"
AUTRE CAS
MessErr="erreur "+l_res+" inconnue"
FIN

FINPROG:

SI PAS ValRetour ALORS
fSauveTexte(fRepEnCours()+"\WinSockFerme.err",MessErr)
FIN

RENVOYER ValRetour