IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Socket qui ne marche qu'un temps limité


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Homme Profil pro
    passionné
    Inscrit en
    Novembre 2023
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : passionné

    Informations forums :
    Inscription : Novembre 2023
    Messages : 6
    Par défaut Socket qui ne marche qu'un temps limité
    Bonjour
    J'ai un circuit Micropython qui se reveille toute les minutes, se connecte au Wifi, ouvre une socket et tente de pousser une chaine de charactere.
    De l'autre coté sur un raspberry j'ai un script python qui ouvre la même socket et essai de la lire.

    Cela marche un certain temps (entre quelques cylcles et quelques heures) mais inevitablement au bout d'un momment le programme coté Raspberry n'arrive plus a lire.
    Si je le redemarre coté Raspberry cela repart...

    J'ai essayé de faire tourner le programme raspberry dans :
    - une boucle "while True" en attente de la socket
    - dans un script lancé par la crontab régulierement

    => meme probleme

    C'est comme si la socket etait saturé au bout d'un certain temps?
    (quand cela ne "marche plus" un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    netstat -tupln |grep 112zz
    tcp        3      0 192.168.xx.yy:112zz    0.0.0.0:*               LISTEN      -
    semble montrer que le process ecoute bien toujours sur le port.

    Le code que je fait tourner coté Raspberry 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
    #!/usr/bin/env python3
     
    import socket
     
    mySocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, fileno=None)
    mySocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    hostname = '192.168.xx.yy'
    portno = 11222
    mySocket.bind((hostname, portno))
     
    mySocket.listen(2)
     
     
    if __name__ == "__main__":
        #while True:
        client, client_addr = mySocket.accept()
        print('Connection established with client at address {}'.format(client_addr))
        message = client.recv(1024).decode()
        print(message)
     
        client.close()
    Une idee de comment debugger ou ameliorer mon code pour que la "connection" ne se bloque pas....

    Merci

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 762
    Par défaut
    Saluit,

    Le code que vous avez posté est celui d'un serveur (listen) qui attend un client, lit le message, l'affiche et termine... ce qui n'est pas cohérent avec la notion de serveur (qui écoute en permanence).

    Et cela ne reflète pas du tout ce que vous racontez.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Futur Membre du Club
    Homme Profil pro
    passionné
    Inscrit en
    Novembre 2023
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : passionné

    Informations forums :
    Inscription : Novembre 2023
    Messages : 6
    Par défaut
    Oui je confirme que j'ai posté le code du Raspberry et donc coté Serveur.
    C'est que j'ai du mal m'exprimer ...

    Le code initial avait un "while True: " que j'ai temporairement retirer pour essayer de debugger.
    Mon Client a l'avantage de se connecter a periode constante.

    le code initiale etait

    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
    #!/usr/bin/env python3
     
    import socket
     
    mySocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, fileno=None)
    mySocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    hostname = '192.168.xx.yy'
    portno = 11222
    mySocket.bind((hostname, portno))
     
    mySocket.listen(2)
     
     
    if __name__ == "__main__":
        while True:
          client, client_addr = mySocket.accept()
          print('Connection established with client at address {}'.format(client_addr))
          message = client.recv(1024).decode()
          print(message)
     
        client.close()
    mais au bout d'un momment bien que le script continue a écouter sur le port, et que le client envoie bien sa demande de connection le serveur ne la recupere pas...

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 762
    Par défaut
    A par l'indentation du client.close(), ce code devrait fonctionner.
    On ne peut pas exclure un problème coté OS ou de ressources (c'est lui qui hère les sockets).
    Mais on est plus dans une logique raspberry / réseau que python.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Futur Membre du Club
    Homme Profil pro
    passionné
    Inscrit en
    Novembre 2023
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : passionné

    Informations forums :
    Inscription : Novembre 2023
    Messages : 6
    Par défaut
    Oups en effet j'ai oublié de l'indenter aussi...

    Je me demandais meme si c'est au niveau de l'OS, si il n'y avait pas moyen de robustifier un peu?
    Par exemple si il accept la connection a "client, client_addr = mySocket.accept()" mais que quelques seconde apres il n'est pas capable de faire le "message = client.recv(1024).decode()" => il ferme la connection et attend la prochaine.
    Cela ne me "gene" pas qu'il puisse de temps en temps ratter des émissions.

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 762
    Par défaut
    Citation Envoyé par ewok002 Voir le message
    Par exemple si il accept la connection a "client, client_addr = mySocket.accept()" mais que quelques seconde apres il n'est pas capable de faire le "message = client.recv(1024).decode()"
    Vous pouvez essayer d'ajouter des timeouts aux sockets mais exploiter les journaux système pour avoir une idée de ce qu'il se passe ou utiliser un débogueur système pour voir ce qu'il se passe serait préférable.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par ewok002 Voir le message
    Je me demandais meme si c'est au niveau de l'OS, si il n'y avait pas moyen de robustifier un peu?
    Cela ne me "gene" pas qu'il puisse de temps en temps ratter des émissions.
    Déjà puisque la liaison n'est pas en mode connecté, pourquoi la mettre en SOCK_STREAM ? Tu as le mode SOCK_DGRAM justement fait pour ce genre de cas (c'est à dire un client qui écrit "de temps en temps" à un serveur qui s'allume "de temps en temps"). A chaque émission, le client précise à qui elle doit aller et c'est à ce moment là que se fait la connection.

    Un exemple...

    Le serveur
    Code python : 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
    #!/usr/bin/env python3
    # coding: utf-8
     
    import socket
    import sys
    import os
     
    class cSocket:
    	def __init__(self, port):
    		self.__port=port
    		self.__connect=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    		self.__connect.bind(("", port))
    		print("socket {} prête à écouter sur le port {}".format(self.__connect, self.__port))
    	# __init__()
     
    	def __del__(self):
    		self.__connect.close()
    		print("socket {} sur port {} terminée".format(self.__connect, self.__port))
    	# __del__()
     
    	# Ecoute
    	def listen(self):
    		while True:
    			try:
    				(data, infos)=self.__connect.recvfrom(1024)
    			except KeyboardInterrupt:
    				break
    			# try
    			try: host=socket.gethostbyaddr(infos[0])[0]
    			except socket.herror as e: host="?"
    			txt=data.decode("utf-8")
    			print("adr=[{}]: [{}]{}".format(host,	txt, " => Arrêt du client" if txt == "EOT" else ""))
    		# while
    		print("socket {} sur port {} terminé !!!".format(self.__connect, self.__port))
    	# listen()
    # class cSocket
     
    if __name__ == "__main__":
    	cSocket(int(sys.argv[1])).listen()
    Tu remarqueras accessoirement que pour le bind(), le serveur n'a pas besoin de mettre une adresse puisque c'est lui-même. Ca t'évite ce hostname = '192.168.xx.yy' inutile de ton code.
    Et ce serveur tu le lances en lui donnant le numéro de port en paramètre.

    Et le client
    Code python : 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
    #!/usr/bin/env python3
    # coding: utf-8
     
    import socket
    import sys
     
    class cSocket:
    	def __init__(self, port, host="localhost"):
    		self.__host=host
    		self.__port=port
    		self.__dialog=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    		print("socket {} prête pour {} sur le port {}".format(self.__dialog, host, port))
    	# __init__()
     
    	def dialogue(self):
    		while True:
    			msg=input("Tapez votre message (EOT pour quitter): ")
    			self.__dialog.sendto(msg.encode("utf-8"), (self.__host, self.__port))
    			if msg == "EOT":
    				print("Client teminé")
    				break
    			# if
    		# while
    	# dialogue()
    # class cSocket
     
    if __name__ == "__main__":
    	cSocket(int(sys.argv[1]), sys.argv[2] if len(sys.argv) > 2 else "localhost").dialogue()
    Lui tu le lances en lui donnant le numéro de port et éventuellement l'adresse du serveur (si le serveur tourne sur un autre host).

    Ensuite dans le client tu tapes ce que tu veux et tout ce que tu tapes est affiché par le serveur (sans perdre quoi que ce soit). Et tu termines avec la string "EOT".
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. [XL-2019] Cellule qui clignote pendant un temps limité
    Par EAU24 dans le forum Macros et VBA Excel
    Réponses: 15
    Dernier message: 23/09/2019, 17h00
  2. Réponses: 2
    Dernier message: 01/12/2009, 07h58
  3. Socket, recv et select qui ne marche pas
    Par Zapan dans le forum Réseau
    Réponses: 18
    Dernier message: 30/06/2006, 20h19
  4. Socket qui ne marche pas
    Par Guillaume602 dans le forum C++
    Réponses: 4
    Dernier message: 15/01/2006, 14h07
  5. Réponses: 9
    Dernier message: 07/05/2003, 12h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo