asyncio et connexion réseau broadcast

a marqué ce sujet comme résolu.
Auteur du sujet

Bonjour,

J’ai écrit un script qui permet de dialoguer sur le réseau en broadcast. Je peux lancer le serveur et le client séparément (deux terminaux), et ils fonctionnent, mais je ne parviens pas à les faire fonctionner en concurrence.

J’ai essayé en me basant sur le cours sur asyncio, mais je n’arrive pas à le mettre en pratique (j’ai des erreurs dès que j’essaie :( ). Pouvez vous me guider pour que ça fonctionne avec mon programme? Voici le code actuel, sans asyncio:

 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
from socket import *
import pickle, asyncio
port=12345

class BrServer(object):
    "Serveur broadcast: découverte d'utilisateurs sur le réseau"

    def __init__(self, port):
        self.s=socket(AF_INET, SOCK_DGRAM)
        self.s.bind(('',port))
        self.status=1

    def start(self):
        while self.status:
            print("écoute...")
            m=self.s.recvfrom(1024)
            reception=pickle.loads(m[0])
            adresse=m[1][0]
            print(reception)
            print( adresse )
            if (reception == 'fin'):
                print ("Commande de fin reçue")
                self.status=0

    def stop(self):
        self.status=0
        print("fin écoute broadcast")

class BrClient(object):
    "Client broadcast: se présenter sur le réseau"

    def __init__(self, port):
        "Initialiser un socket"
        self.s=socket(AF_INET, SOCK_DGRAM)
        self.s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
        self.port=port

    def send(self, message):
        "Envoyer un message"
        self.s.sendto(pickle.dumps(message),('255.255.255.255',self.port))

# On lance le serveur
ecouter=BrServer(port)
ecouter.start()

# On lance le client (ne sera pas exécuté avant la fin du serveur)
parler=BrClient(port)
parler.send("hello")
parler.send("4688")
parler.send("fin")
parler.send(":)")
+0 -0

Tu n’as pas réellement besoin de asyncio je pense, il faudrait juste utiliser la même boucle d’évènements (du type select) sur les deux sockets (celle du serveur, et celle du client) sur des évènements de lecture.

Dans cet exemple, on y monitore qu’une seule socket, mais tu peux très bien y mettre les deux : https://docs.python.org/3.5/library/selectors.html#examples

Ce serait alors un truc du genre (en se basant sur ton code) :

1
2
3
4
5
6
7
8
sel.register(ecouter.s, selectors.EVENT_READ, ecouter.start)
sel.regsiter(parler.s, selectors.EVENT_READ, ecouter.send)

while True:
    events = sel.select() # Je reçois les events pour la socket client et aussi pour la socket serveur
    for key, mask in events:
        callback = key.data
        callback(key.fileobj, mask) # j'appelle le bon handler, que ce soit le client ou le serveur

Édité par sgble

+0 -0
Auteur du sujet

Merci pour ton exemple. J’ai réussi à le faire fonctionner, mais je ne crois pas que ce soit l’idéal non plus: j’ai les deux objets qui attendent des données en même temps, mais dans la pratique je ne peux pas envoyer de données à parler, car mon programme est coincé dans la boucle while true

Ce système (selectors) permet de gérer plusieurs entrées en même temps (plusieurs connexions réseau par exemple), mais quand mon programme attend des données venant du réseau, je ne peux pas en même temps écrire (je crois..?)

Je suis en train de faire mon programme avec les threads, et pour l’instant je crois que je m’en sors :)

En fait, mon programme final aura une interface graphique(Qt5), et devra interagir avec le réseau. J’en dirai davantage dans la section Vos Projets

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte