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

Réseau/Web Python Discussion :

Simulation Mini Chat


Sujet :

Réseau/Web Python

  1. #1
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut Simulation Mini Chat
    Bonjour,

    Maintenant que je sais identifier des clients différents qui se connectent au serveur, je me suis dit qu'il fallait aller un peu plus loin, et je souhaite donc faire un mini-Chat. Un truc très simple (en théorie du moins ).
    Au départ, j'ai simplement modifié légèrement mon serveur pour qu'il prenne le nom de mon client, et transmette les messages reçu aux autres clients. Mais ça ne fonctionnait pas correctement, mon client recevait le message (de l'autre) uniquement quand il tapait quelque chose d'abord.
    Donc l'input bloquait la réception.
    Du coup, on m'a soufflé que le thread était une bonne idée.
    Mais.....ce que j'ai fait ne fonctionne pas comme je le souhaite.
    Les codes maintenant.
    Le 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
    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
    52
    import socket
    import select
     
    hote = ''
    port = 12800
     
    connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connexion_principale.bind((hote, port))
    connexion_principale.listen(5)
    print("Le serveur écoute à présent sur le port {}".format(port))
     
    serveur_lance = True
    clients_connectes = []
    clients_sockets = {}
    n = ' '
    while serveur_lance:
        connexions_demandees, wlist, xlist = select.select([connexion_principale],
            [], [], 0.05)
     
        for connexion in connexions_demandees:
            connexion_avec_client, infos_connexion = connexion.accept()
            clients_connectes.append(connexion_avec_client)
     
        clients_a_lire = []
        try:
            clients_a_lire, wlist, xlist = select.select(clients_connectes,[], [], 0.05)
     
        except select.error:
            pass
        else:
            for client in clients_a_lire :
                if client not in clients_sockets :
                    client.send(b"Bienvenue sur le Tchat")
                    n = client.recv(1024)
                    n = n.decode()
                    clients_sockets.setdefault(connexion_avec_client,n)
     
                msg_recu = client.recv(1024)
                for client_tchat in clients_sockets :
                    msg_a_transmettre = clients_sockets[client_tchat].encode()\
                                        + b" : " + msg_recu
                    client_tchat.send(msg_a_transmettre)
                    print(msg_a_transmettre.decode())
     
                if msg_recu == "fin":
                    serveur_lance = False
     
    print("Fermeture des connexions")
    for client in clients_connectes:
        client.close()
     
    connexion_principale.close()
    Les threads :
    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
    35
    36
    37
    38
    39
    40
    41
     
    from threading import Thread, RLock
     
     
     
     
    class Client_Rec(Thread):
     
        """Thread chargé simplement d'afficher les message envoyés par le serveur."""
     
        def __init__(self,connexion):
            Thread.__init__(self)
            self.connexion_avec_serveur = connexion
     
        def run(self):
            """Code à exécuter pendant l'exécution du thread."""
            msg_recu = ''
            while msg_recu :
                msg_recu = self.connexion_avec_serveur.recv(1024)
                print(msg_recu.decode())
     
     
     
    verrou = RLock()
     
    class Client_Envoi(Thread):
     
        """Thread chargé simplement d'envoyer des messages au serveur."""
     
        def __init__(self, connexion):
            Thread.__init__(self)
            self.connexion_avec_serveur = connexion
     
        def run(self):
            """Code à exécuter pendant l'exécution du thread."""
            msg_a_envoyer = b""
            while msg_a_envoyer != b"fin":
                with verrou:
                    msg_a_envoyer = input("> ")
                    msg_a_envoyer = msg_a_envoyer.encode()
                    self.connexion_avec_serveur.send(msg_a_envoyer)
    et les clients :
    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
    import socket
    from Tchat_client_thread import*
     
    hote = "localhost"
    port = 12800
     
    connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connexion_avec_serveur.connect((hote, port))
    print("Connexion établie avec le serveur sur le port {}".format(port))
    print("Quel est votre nom ?")
     
    thread_Rec = Client_Rec(connexion_avec_serveur)
    thread_Envoi = Client_Envoi(connexion_avec_serveur)
     
    thread_Rec.start()
    thread_Envoi.start()
     
    thread_Rec.join()
    thread_Envoi.join()
     
     
    print("Fermeture de la connexion")
    connexion_avec_serveur.close()
    Désolée de mettre tout le code. Mais je ne sais pas identifier ce que j'ai mal fait.
    Est-ce mon verrou ? je l'ai mis sur l'input, parce que je voulais que la réception des messages soit prioritaire sur l'envoi. Ce n'était pas ce qu'il fallait faire ? Ou alors c'est autre chose ?

    D'avance, un grand merci à ceux qui auront la patience de se pencher sur mes petits problèmes

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    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 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Salut,

    Citation Envoyé par RowanMayfair Voir le message
    Mais.....ce que j'ai fait ne fonctionne pas comme je le souhaite.
    Certes mais si vous ne précisez pas ce que vous souhaitez et en quoi le fonctionnement de votre code ne le fait pas....

    On est bien embêté car, çà, à priori, çà devrait marchoter...

    Sauf que comme on n'écrit pas une application réseau de façon aussi disons "dilettante", il y aurait plein de chose à revoir... et ce n'est peut être pas le sujet (en tous cas, la programmation réseau s'apprend et il y a tellement de bons tutos pour çà que...).

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

  3. #3
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    difficile de décrire ce qui se passe.
    Un test.
    Sur le serveur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Le serveur écoute à présent sur le port 12800
    Martine : Martine va à la plage
    Martine : pas de messages de l'autre client ?
    ClaudetteClaudette va à la plage : pas de messages de l'autre client ?
    Martine : et Claudette ,
    ClaudetteClaudette va à la plage : et Claudette ,
    Martine : ça se mélange
    ClaudetteClaudette va à la plage : ça se mélange
    Martine : client 2
    ClaudetteClaudette va à la plage : client 2
    Martine : client 1
    ClaudetteClaudette va à la plage : client 1
    Voilà tout est mélangé, le serveur affiche le message de l'un en l'affichant sur les 2...bref, tout mélangé
    Et sur les shell des clients, il n'y a que leurs propres messages qui s'affichent, le serveur ne transmet pas les messages des autres clients.

    L'objectif, c'est que les messages de Claudette s'affichent sur le shell de Martine au fur et à mesure, et réciproquement. Pour qu'elles puissent se répondre.

    Je n'ai pas la prétention d'apprendre la programmation réseau. Je souhaite rester au stade de l'initiation. Je ne comptais pas aller + loin que ce mini-Chat sur réseau local...mais j'aimerai bien réussir ça quand même.

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    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 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Citation Envoyé par RowanMayfair Voir le message
    Voilà tout est mélangé, le serveur affiche le message de l'un en l'affichant sur les 2...bref, tout mélangé
    ah ben oui mais... il faut définir un protocole entre serveur et client.
    Par exemple, si vous écrivez:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            for client in clients_a_lire :
                if client not in clients_sockets :
                    client.send(b"Bienvenue sur le Tchat")
                    n = client.recv(1024)
                    n = n.decode()
                    clients_sockets.setdefault(connexion_avec_client,n)
    vous supposez qu'après avoir ouvert la connexion, le client attend gentiment le message de bienvenue du serveur pour lui expédier la chaine de caractère qui permettra d'identifier le client.

    De plus, cette étape là suppose qu'il n'y a plus rien à lire pour ce client là...

    Après côté client, on doit avoir aussi un bout de code qui attend le message de bienvenue du serveur, expédie l'identifiant,...

    La difficulté avec ce genre de code, c'est que vous avez un état "global" qui doit entre cohérent entre clients et serveur et plus seulement un état global réduit aux variables d'un code qui s'exécute gentiment dans son coin.

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

  5. #5
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    ah ben oui mais... il faut définir un protocole entre serveur et client.
    Par exemple, si vous écrivez:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            for client in clients_a_lire :
                if client not in clients_sockets :
                    client.send(b"Bienvenue sur le Tchat")
                    n = client.recv(1024)
                    n = n.decode()
                    clients_sockets.setdefault(connexion_avec_client,n)
    vous supposez qu'après avoir ouvert la connexion, le client attend gentiment le message de bienvenue du serveur pour lui expédier la chaine de caractère qui permettra d'identifier le client.

    (...)

    - W
    En effet, cette étape là déjà ne fonctionne pas correctement. Le message de bienvenue du serveur ne s'affiche pas sur le client. Par contre, le serveur prend bien le premier message du client comme variable n, c'est à dire son nom. Ou presque, parce que le pour le 2ème client il a pris les 2 premiers messages comme identifiant.

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    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 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Citation Envoyé par RowanMayfair Voir le message
    Ou presque, parce que le pour le 2ème client il a pris les 2 premiers messages comme identifiant.
    Ça c'est une autre specificité de la programmation réseau.
    Vous pensez "messages" en croyant que les .send d'un côte doivent, de l'autre côte, correspondre aux .recv...

    Alors qu'en fait, TCP/IP peut très bien retourner le début de ce qui a été expédié par un .send ou le contenu expédié par plusieurs .send pour un seul .recv. La seule chose que vous garantit la couche transport (le T dans TCP), c'est que les bytes seront, s'ils arrivent, reçus dans le même ordre qu'ils ont été expédiés.

    Et pour avoir des "messages", il va falloir découper ce flot de bytes pour délimiter ce qu'on pourra appeler "message". Histoire de s'assurer qu'on a tout reçu avant d'en faire quelque chose et de ne pas bouffer un bout du message suivant.

    Par exemple, dans votre cas, vous échangez des "lignes".

    Et pour découper le message en lignes, s'assurer que ce que vous avez reçu se termine bien par "fin de ligne" ('\r\n' ou '\n' par exemple) et de l'expédier explicitement - ce que vous n'expédiez pas n'arrivera jamais.

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

  7. #7
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    ce qui me gène le +, c'est que je n'arrive pas à ce que le serveur envoie à l'autre client les messages du 1er client.
    Les noms...tant pis, pour l'instant, c'est secondaire.

    Du coup j'ai re-modifié le serveur, pour laisser tomber les noms, et laisser des numéros qui s'incrémentent pour les identifier.
    Sauf que le serveur n'envoie pas les messages aux clients.

    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
     clients_a_lire = []
        try:
            clients_a_lire, wlist, xlist = select.select(clients_connectes,[], [], 0.05)
     
        except select.error:
            pass
        else:
            for client in clients_a_lire :
     
                msg_recu = client.recv(1024)
     
                msg_a_trans = "Client {} : {}".format(clients_sockets[client],msg_recu.decode())
                for client_tchat in clients_sockets :
                    client_tchat.send(msg_a_trans.encode())
     
     
     
                if msg_recu == "fin":
                    serveur_lance = False
    Je ne comprends pas.
    J'ai bien un "send" coté serveur, et un "recv" côté client. Et pourtant, le serveur n'envoie pas mon msg_a_trans

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    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 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Citation Envoyé par RowanMayfair Voir le message
    J'ai bien un "send" coté serveur, et un "recv" côté client. Et pourtant, le serveur n'envoie pas mon msg_a_trans
    Dire "le serveur n'envoie pas mon msg_a_trans", c'est s'assurer qu'on passe bien dans le .send de la séquence:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
                for client_tchat in clients_sockets :
                    client_tchat.send(msg_a_trans.encode())
    avec la commande magique "print".

    Et si on n'y passe pas, c'est que clients_sockets est sans doute vide. Ce qui se vérifie avec un autre "print" avant la boucle.

    Cela vérifié, si le serveur passe par ce .send, il faut vérifier, côté client que le .recv peut effectivement se faire.

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

  9. #9
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    j'ai vérifié, en tout cas le .send fonctionne, du moins il y a ce qu'il doit y avoir dans "msg_a_trans"

    coté client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Client_Rec(Thread):
     
        """Thread chargé simplement d'afficher les message envoyés par le serveur."""
     
        def __init__(self,connexion):
            Thread.__init__(self)
            self.connexion_avec_serveur = connexion
     
        def run(self):
            """Code à exécuter pendant l'exécution du thread."""
            msg_recu = ''
            while msg_recu :
                msg_recu = self.connexion_avec_serveur.recv(1024)
                print(msg_recu.decode())
    et en effet rien ne s'affiche côté client, en tout cas pas les messages reçu. Il ne reçoit rien.

  10. #10
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    Donc le problème venait de mon while.
    remplacé par while 1, ça fonctionne mieux. En tout cas, je fini par les avoir. Par contre il faut que je fasse plusieurs entrées pour récupérer les messages de l'autre client...mais c'est inévitable.
    J'ai trouvé un petit tchat tout fait dans le bouquin de Swinnen, c'est comme ça qu'il fonctionne, pas mieux.
    Par contre il faut que je trouve comment envoyer uniquement aux clients qui ne sont pas auteurs dudit message.(edit : ça c'était pas le plus compliqué...)
    Edit : et aussi du coup ma connexion ne se ferme plus......c'est dommage

    Edit 2 : c'est bon ça fonctionne.
    J'ai tellement galéré sur rien du tout que je n'apprécie même pas que ce soit fini.

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    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 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Salut,

    Citation Envoyé par RowanMayfair Voir le message
    J'ai tellement galéré sur rien du tout que je n'apprécie même pas que ce soit fini.
    Pour l'instant, vous vous êtes juste frottée aux bases de la programmation.
    Et encore, regardez vos dernières erreurs sur "for" et "while", dès qu'on vous perturbe un peu vous y perdez le peu que vous avez appris.

    Vous avez entre ouvert les portes de la programmation d'interfaces graphiques, des bases de données, des réseaux,... et vous vous rendez compte que ces univers là ont leurs propres difficultés qui n'ont rien à voir avec la programmation "basique" à proprement parler.

    L'étape suivante pourrait être la lecture de codes écrits par d'autres. Vous avez plein de bibliothèques sur PyPI (ou même les bibliothèques standards que vous utilisez déjà). Maintenant que vous savez lire, ayez la curiosité d'aller voir comment çà fonctionne.

    Une autre étape est aussi la lecture de la documentation Python. Histoire de voir les fonctionnalités d'une classe, d'une bibliothèque,...

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

  12. #12
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    Oui je suis consciente qu'il faut que je bosse encore mes bases.

    Dans l'immédiat, je vais terminer mon TP Roboc (multi-joueur avec des tests unitaires...y a du boulot encore ) mais par la suite j'envisage déjà de me trouver des exercices sur les bases Python.

    Et en effet la documentation Python pourrait être intéressante. Disons qu'il y a beaucoup beaucoup de choses, j'ai peur de ne pas en retenir grand chose. Faut voir.

    Et lire des codes déjà fait....j'ai pas l'impression d'être encore prête. Mais pourquoi pas. Je pourrai déjà venir lire les questions des autres sur les forums pour commencer

    Et un jour quand même, je ferai une pause Python pour suivre le cours sur les bases de données. J'ai à peine effleuré le sujet, mais je sens que je vais adorer ça. Sans doute parce que j'en ait beaucoup manipulé (+ ou - consciemment) dans mon ex-vie professionnelle.

  13. #13
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    Bonjour,

    Je reprends ce fil pour éviter d'en créer un autre, vu qu'en gros je suis toujours sur le même type de scripts. Avec le même type de problèmes

    Donc, un extrait de mon 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
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    serveur_lance = True
    joueurs_connectes = []
    joueurs_sockets = {} # dictionnaire des joueurs {socket:joueur 1, etc}
    joueur = 1  # incrémentation : attribue un n° de joueur au fur et à mesure des
                # connexions
     
    while serveur_lance :
        connexions_demandees,wlist,xlist = select.select([connexion_principale],
                                                         [],[],0.05)
        for connexions in connexions_demandees :
            connexion_avec_joueur,infos_connexion = connexions.accept()
            joueurs_connectes.append(connexion_avec_joueur)
            joueurs_sockets.setdefault(connexion_avec_joueur,joueur)
            joueur += 1
     
        joueurs_a_lire : []
     
        try :
            joueurs_a_lire,wlist,xlist = select.select(joueurs_connectes,
                                                       [],[],0.05)
        except :
            pass
        else :
     
            rep = ' '
            for sockets,num_joueurs in joueurs_sockets.items() :
                bienvenue = "Bienvenue Joueur {} !".format(num_joueurs)
                sockets.send(bienvenue.encode())
     
                while rep.lower() != "c" :
                    dem = "Appuyez sur 'c' pour démarrer une partie : "
                    sockets.send(dem.encode())
                    rep = sockets.recv(5).decode()
                sockets.send(b"C'est parti ! ")
                sockets.send(b"Bienvenue dans Roboc, le plus sympa des labyrinthes\n")
                sockets.send(b"Liste des cartes :  \n")
    ce qui me chagrine est à partir de la ligne 26
    dès le début ça ne fonctionne pas comme je le souhaite, et je ne comprends pas pourquoi.
    joueurs_sockets étant bien un dictionnaire avec le socket de chaque joueur qui se connecte en clé, et un n° de joueur en valeur.

    je connecte 2 clients, pour le 1er il m'envoie bien "Bienvenue Joueur 1" et, ensuite.....il envoie 2 fois au joueur 1 "appuyez sur c pour démarrer".....et pendant ce temps-là, il n'envoie rien du tout au joueur 2. Le néant. Pas de bienvenue, de proposition de taper c.

    le joueur 2 est pourtant bien connecté.

    et c'est que le début, je n'ai même pas testé la suite du programme

    Bref, comment savoir ce qui se passe ?

  14. #14
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    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 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Salut,

    Citation Envoyé par RowanMayfair Voir le message
    Bref, comment savoir ce qui se passe ?
    La commande "print" devrait vous permettre de voir ce qui a été reçu et on s'attend à ce que ce ne soit pas égal à "c".

    Pour le reste, je vous avais suggéré de réfléchir à que ce sont les messages échangés dans cette réponse.
    Si vous ne comprenez pas ce que je raconte, demandez des précisions plutôt que partir sur une autre piste... Car, si cette chose là n'est pas réalisée dans votre code, çà ne marchera jamais.

    Pour digresser un peu et regarder les choses autrement. Imaginez une application tkinter avec 2 Frames superposées contenant 3 widgets: Entry, Button, Text.
    La première Frame représente client 1, la deuxième client 2.
    Chaque fois qu'un client veut causer, il tape des caractères dans l'Entry et valide en appuyant sur le Button.
    Le callback associé au Button récupère le texte, l'ajoute dans une liste clientn_send et efface le contenu de l'Entry.

    Côté serveur, on exécute un callback avec .after qui va régulièrement vider les listes clientn_send pour remplir des listes clientn_recv.

    Côté clients, on a aussi un callback qui s'exécute régulièrement via .after pour vider les listes clientn_recv et afficher le contenu dans le widget Text.

    Une fois que çà fonctionne, vous remplacez les listes de chaines de caractères (nos messages) par de simples listes de caractères (et vous devriez voir le bazar). Cette dernière partie ne sert à rien: vu que les callbacks sont sérialisés, il faut bien plus pour détruire l'unité logique de message dans ce cas. Mais cela devrait suffire pour avoir une notion de "protocole" sans utiliser de réseau (et donc à priori plus simple ou moins déroutant).

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

  15. #15
    Membre régulier Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 47
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Points : 89
    Points
    89
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,



    La commande "print" devrait vous permettre de voir ce qui a été reçu et on s'attend à ce que ce ne soit pas égal à "c".

    Pour le reste, (...)

    - W
    en effet. Je partais du principe que mon dictionnaire se constituait correctement, or ce n'est pas le cas.

    il n'y a que le 1er client connecté qui apparaît. Alors que le 2ème m'affiche bien qu'il est connecté au serveur. Mais son socket n'apparaît pas dans le dictionnaire joueurs_sockets. Donc normal que le serveur ne lui envoie pas de message au client 2, même pas le message de bienvenue.

  16. #16
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 242
    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 242
    Points : 36 699
    Points
    36 699
    Par défaut
    Citation Envoyé par RowanMayfair Voir le message
    Mais son socket n'apparaît pas dans le dictionnaire joueurs_sockets. Donc normal que le serveur ne lui envoie pas de message au client 2, même pas le message de bienvenue.
    Ça c'est le deuxième problème, le premier était:
    Citation Envoyé par RowanMayfair Voir le message
    je connecte 2 clients, pour le 1er il m'envoie bien "Bienvenue Joueur 1" et, ensuite.....il envoie 2 fois au joueur 1 "appuyez sur c pour démarrer".....
    Et pour ce deuxième problème, je vous ai suggéré une petite application avec tkinter pour comprendre un peu la notion de protocole.

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

Discussions similaires

  1. [Wamp] Réalisation mini chat
    Par levirus93700 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 13
    Dernier message: 05/05/2008, 09h58
  2. [AJAX] Mini-Chat Basique
    Par foester dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 10/08/2007, 15h45
  3. Mini-chat en PHP
    Par azmodai dans le forum Langage
    Réponses: 10
    Dernier message: 25/07/2007, 17h38
  4. Mini Chat - sémaphores et mémoire partagée
    Par highman dans le forum Réseau
    Réponses: 4
    Dernier message: 02/04/2007, 22h54
  5. [Winsock] Quel est le port pour un mini-chat
    Par Jihnn dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 12/02/2007, 04h20

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