Précédent   Forum du club des développeurs et IT Pro > Autres langages > Python & Zope > Réseau/Web
Réseau/Web Forum d'entraide sur Python et le réseau/Web
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 16/02/2013, 01h11   #1
bromy
Invité régulier
 
Homme
Lyceen
Inscription : novembre 2012
Messages : 28
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Lyceen
Secteur : Service public

Informations forums :
Inscription : novembre 2012
Messages : 28
Points : 5
Points : 5
Par défaut Reseau - Tkinter

Bonsoir,

Dans le cadre d'un projet scolaire, nous avons essayer, grace au module Socket et Tkinter, de faire deplacer un pion sur map, mais cela en reseau

En gros, notre serveur affiche notre map et notre pion, pendant que le client s'occupe de le faire bouger.

Seulement, lorsque le pion a fait 5 cm sur la map client, il n'a meme pas fait 2mm sur la map serveur. Le pion se deplace beaucoup moins vite sur le serveur que sur le client.

Serveur :

Code :
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
 
##### SERVEUR TCP - Multi-clients #####
 
import socket
import tkinter as tk
from tkinter import *
import select
 
HOTE = 'localhost'   # quelconque
PORT = 12345
TAILLE_MAX_PAQUET = 1024
recu = '' 
sSrv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sSrv.bind((HOTE, PORT))
sSrv.listen(5)  # Nbre maxi acceptés "en parallèle"
print("Le serveur écoute à présent sur le port", PORT)
 
clients_connectes = []
serveur_ecoute = True
 
root2 = Tk()
fenetre_plateau=Canvas(root2, width="487", height="315")
photo = PhotoImage(file="mapcouper.gif")
fenetre_plateau.create_image(243.5, 157.5, image=photo)
fenetre_plateau.pack()
 
 
 
carrebleu = [[11,94], [53,94], [11,207], [53,207]]
carrebleu2 = [[438,92], [478,92], [438,206], [478,206]]
x = 240
y = 145
r = 8
dx = 0
dy = 0
couleur="red"
 
 
def move(event):
    x = fenetre_plateau.canvasx(event.x)
    y = fenetre_plateau.canvasy(event.y)
    #if (carrebleu2[0][0] < event.x < carrebleu2[1][0] and carrebleu2[0][1] < event.y < carrebleu2[2][1]) or (carrebleu[0][0] < event.x < carrebleu[1][0] and carrebleu[0][1] < event.y < carrebleu[2][1]):
 
 
def cercle():
    return fenetre_plateau.create_oval(210, 210, 230, 230, fill=couleur,tag = "pion")
 
def up (event:None):
    global dx
    global dy
    global up
    up=True
    dx = 0
    dy = -1
 
def down (event:None):
    global dx
    global dy
    global down
    down=True
    dx = 0
    dy = 1
 
def left (event:None):
    global dx
    global dy
    global left
    left=True
    dx = -1
    dy = 0
 
def right (event:None):
    global dx
    global dy
    global right
    right=True
    dx = 1
    dy = 0
 
 
cercle()
 
root2.bind('<1>', move)
root2.bind('<Up>', up)
root2.bind('<Down>', down)
root2.bind('<Left>', left)
root2.bind('<Right>', right)
 
while serveur_ecoute:    # Boucle d'écoute du serveur
    # (1) On vérifie si des nouveaux clients demandent à se connecter
    #  => on écoute le serveur, maxi pendant 0.05 sec.
    connexions_demandees, wlist, xlist = select.select([sSrv],
                                                       [], [], 0.05)
    # en_ecoute, en_ecriture, en_except., pour select.select
    for connexion in connexions_demandees:
        sCli, infos_connexion = connexion.accept()
        # On ajoute le socket connecté à la liste des clients connectés
        clients_connectes.append(sCli)
 
    # (2) Maintenant, on écoute la liste des clients *connectés*
    liste_sCli_a_lire = []
    try:        # sinon, exception levée si la liste des clients est vide
        liste_sCli_a_lire, wlist, xlist = select.select(clients_connectes,
                                                        [], [], 0.05)
    except select.error:
        pass    # Ne rien faire s'il n'y en a pas
    else:
        # On parcourt la liste des clients à lire
        for sCli in liste_sCli_a_lire:
            msg_recu = sCli.recv(TAILLE_MAX_PAQUET) # octets, donc 
            recu = str(msg_recu, encoding="utf-8")  #  à encoder...
            print("'", recu, "' reçu de",       # message,
                  sCli.getpeername()[0],        #  IP et
                  "/", sCli.getpeername()[1])   #  port de l'envoyeur            
            ### Facultatif : accusé de réception #######################
            sCli.send(bytes("'"+recu+"' bien reçu !", encoding="utf-8"))
            ############################################################
    if recu == 'UP':
        dx = 0
        dy = -1
 
    if recu == 'DOWN':
        dx = 0
        dy = 1
 
    if recu == 'LEFT':
        dx = -1
        dy = 0
 
    if recu == 'RIGHT':
        dx = 1
        dy = 0
 
 
    recu=''
 
    fenetre_plateau.move("pion", dx,dy)
    fenetre_plateau.update()
    fenetre_plateau.after(10)
 
 
 
 
 
 
 
 
print("Fermeture des connexions au serveur")
for sCli in clients_connectes:
    sCli.close()
sSrv.close()
Client :
Code :
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
 
##### CLIENT TCP #####
 
import socket
import tkinter as tk
 
HOTE = 'localhost' 
PORT = 12345 
TAILLE_MAX_PAQUET = 1024
up = False
down = False
left = False
right = False
msg_a_envoyer = ''
 
 
sCli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sCli.connect((HOTE, PORT)) 
print("Connexion établie avec le serveur sur le port", PORT)
#############################################
 
from tkinter import *
 
root2 = Tk()
fenetre_plateau=Canvas(root2, width="487", height="315")
photo = PhotoImage(file="mapcouper.gif")
fenetre_plateau.create_image(243.5, 157.5, image=photo)
fenetre_plateau.pack()
 
 
 
carrebleu = [[11,94], [53,94], [11,207], [53,207]]
carrebleu2 = [[438,92], [478,92], [438,206], [478,206]]
x = 240
y = 145
r = 8
dx = 0
dy = 0
couleur="red"
 
 
def move(event):
    x = fenetre_plateau.canvasx(event.x)
    y = fenetre_plateau.canvasy(event.y)
    #if (carrebleu2[0][0] < event.x < carrebleu2[1][0] and carrebleu2[0][1] < event.y < carrebleu2[2][1]) or (carrebleu[0][0] < event.x < carrebleu[1][0] and carrebleu[0][1] < event.y < carrebleu[2][1]):
 
 
def cercle():
    return fenetre_plateau.create_oval(210, 210, 230, 230, fill=couleur,tag = "pion")
 
def up (event:None):
    global dx
    global dy
    global up
    up=True
    dx = 0
    dy = -1
 
def down (event:None):
    global dx
    global dy
    global down
    down=True
    dx = 0
    dy = 1
 
def left (event:None):
    global dx
    global dy
    global left
    left=True
    dx = -1
    dy = 0
 
def right (event:None):
    global dx
    global dy
    global right
    right=True
    dx = 1
    dy = 0
 
 
cercle()
 
root2.bind('<1>', move)
root2.bind('<Up>', up)
root2.bind('<Down>', down)
root2.bind('<Left>', left)
root2.bind('<Right>', right)
 
 
 
 
 
###################################################
 
while 1:
    fenetre_plateau.move("pion", dx,dy)
    fenetre_plateau.update()
    fenetre_plateau.after(10)
    # Saisie du message
 
    if up:
        msg_a_envoyer = 'UP'  
    elif down:
        msg_a_envoyer = 'DOWN'
    elif left:
        msg_a_envoyer = 'LEFT'
    elif right:
        msg_a_envoyer = 'RIGHT'
    else:
        fenetre_plateau.update()
 
    # Envoi du message
    if msg_a_envoyer == 'UP' or  msg_a_envoyer == 'DOWN' or msg_a_envoyer == 'LEFT' or msg_a_envoyer == 'RIGHT':
        envoi = bytes(msg_a_envoyer, encoding="utf-8")
        sCli.send(envoi)
 
 
    # Reception de l'accusé, si le serveur en envoie un
        msg_recu = sCli.recv(TAILLE_MAX_PAQUET) # octets, donc 
        recu = str(msg_recu, encoding="utf-8")  #  à encoder...
        print(recu)
        up = False
        down = False
        left = False
        right = False
        msg_a_envoyer = ''
 
    #########################################################
fen.mainloop()
J'aimerais savoir d'ou vient cette "latence" sur le serveur.

Autre chose, je commence dans le reseau, et meme dans la programmation, auriez vous des conseils pour organiser notre code, car j'ai comme l'impression qu'on a coder ca tres mal.

Bonne soiree
bromy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2013, 08h52   #2
PauseKawa
Expert Confirmé
 
Avatar de PauseKawa
 
Homme Patrice BLANGARIN
Technicien Help Desk, maintenance, réseau, système et +
Inscription : juin 2006
Messages : 2 613
Détails du profil
Informations personnelles :
Nom : Homme Patrice BLANGARIN
Localisation : France, Hérault (Languedoc Roussillon)

Informations professionnelles :
Activité : Technicien Help Desk, maintenance, réseau, système et +
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2006
Messages : 2 613
Points : 3 724
Points : 3 724
Bonjour,

Vous comprenez bien que si c'est lent c'est que le code est occupé à autre chose, ici principalement dans la partie réseau.
Pour plus de 'réactivité' vous devez séparer GUI et réseau et cela passe (entre autre) par un thread.
Le souci c'est que sous Tkinter vous ne pouvez/devez pas toucher aux éléments graphique à partir d'un thread. Une solution est de passer par le module queue:
Un exemple rapide sans trop toucher a votre partie réseau.
Code :
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import socket
from tkinter import *
import select
import queue
import threading
 
 
class Serveur(threading.Thread):
    def __init__(self, queue, HOTE='localhost', PORT=12345):
        threading.Thread.__init__(self)
        self.queue = queue
        self.taille_max_paquet = 1024
        self.sSrv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sSrv.bind((HOTE, PORT))
        self.sSrv.listen(5)
        print("Le serveur écoute à présent sur le port", PORT)
        self.clients_connectes = []
        self._stopevent = threading.Event()
    def run(self):
        while not self._stopevent.isSet():
            connexions_demandees, wlist, xlist = select.select([self.sSrv], [], [], 0.05)
            for connexion in connexions_demandees:
                sCli, infos_connexion = connexion.accept()
                self.clients_connectes.append(sCli)
            liste_sCli_a_lire = []
            try:
                liste_sCli_a_lire, wlist, xlist = select.select(self.clients_connectes, [], [], 0.05)
            except (select.error, ValueError):
                pass
            for sCli in liste_sCli_a_lire:
                msg_recu = sCli.recv(self.taille_max_paquet) 
                recu = str(msg_recu, encoding="utf-8")
                cli = sCli.getpeername()
                print("'%s' reçu de %s/%s" % (recu, cli[0], cli[1]))
                sCli.send(bytes("'"+recu+"' bien reçu !", encoding="utf-8"))
                self.queue.put(recu)
        print("Fin du thread")
        print("Fermeture des connexions au serveur")
        for sCli in self.clients_connectes:
            sCli.close()
        self.sSrv.close()
    def stop(self):
        self._stopevent.set()
 
 
def update_gui():
    global tomove
    try:
        recu = Eventqueue.get_nowait()
        if recu:
            tomove = recu
    except queue.Empty:
        pass
    if tomove:
        dx, dy = movedic[tomove]
        fenetre_plateau.move("pion", dx, dy)
        fenetre_plateau.update_idletasks()
    root2.after(10, update_gui)
 
 
def OnQuit():
    s.stop()
    root2.destroy()
 
 
if __name__ == "__main__":
    Eventqueue = queue.Queue()
    tomove = None
    couleur="red"
    movedic = {'UP':(0, -1), 'DOWN':(0, 1), 'LEFT':(-1, 0), 'RIGHT':(1, 0)}
 
    root2 = Tk()
    fenetre_plateau = Canvas(root2, width="487", height="315")
    # photo = PhotoImage(file="mapcouper.gif")
    # fenetre_plateau.create_image(243.5, 157.5, image=photo)
    fenetre_plateau.pack()
    fenetre_plateau.create_oval(210, 210, 230, 230, fill=couleur, tag="pion")
    s = Serveur(Eventqueue)
    s.start()
    update_gui()
    root2.bind('<Up>', lambda e: Eventqueue.put('UP'))
    root2.bind('<Down>', lambda e: Eventqueue.put('DOWN'))
    root2.bind('<Left>', lambda e: Eventqueue.put('LEFT'))
    root2.bind('<Right>', lambda e: Eventqueue.put('RIGHT'))
    root2.protocol("WM_DELETE_WINDOW", OnQuit)
    root2.mainloop()
    s.stop()
(J'ai essayer de garder le plus possible de votre code. Donc exemple a corriger)

@+
__________________
Merci d'utiliser le forum pour les questions techniques.
PauseKawa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2013, 12h14   #3
bromy
Invité régulier
 
Homme
Lyceen
Inscription : novembre 2012
Messages : 28
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Lyceen
Secteur : Service public

Informations forums :
Inscription : novembre 2012
Messages : 28
Points : 5
Points : 5
Merci, je vais regarder tout ca.

Une autre chose, je n'arrive pas a comprendre pourquoi lorsque je lance mon client, le pion du serv part vers le haut sans meme appui de la touche Up (J'avais deja ca avant)

Autre chose, le pion va certe, beaucoup plus vite, mais il ne va toujours pas aussi vite que celui du client, il n'y aura pas moyen de les mettres a vitesse egale ?
bromy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2013, 13h27   #4
PauseKawa
Expert Confirmé
 
Avatar de PauseKawa
 
Homme Patrice BLANGARIN
Technicien Help Desk, maintenance, réseau, système et +
Inscription : juin 2006
Messages : 2 613
Détails du profil
Informations personnelles :
Nom : Homme Patrice BLANGARIN
Localisation : France, Hérault (Languedoc Roussillon)

Informations professionnelles :
Activité : Technicien Help Desk, maintenance, réseau, système et +
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2006
Messages : 2 613
Points : 3 724
Points : 3 724
Bonjour,

Vous n'avez pas donner du code fonctionnel pour le moment (def up (event:None): ) : Pouvez vous donner le code que vous utilisez ? Cela vas aider pour la suite.
Sinon pour votre déplacement c'est que votre variable doit sans doute être à 'UP' dans le code que vous utilisez : A voir avec du code fonctionnel pour vous.

@+
__________________
Merci d'utiliser le forum pour les questions techniques.
PauseKawa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2013, 13h42   #5
PauseKawa
Expert Confirmé
 
Avatar de PauseKawa
 
Homme Patrice BLANGARIN
Technicien Help Desk, maintenance, réseau, système et +
Inscription : juin 2006
Messages : 2 613
Détails du profil
Informations personnelles :
Nom : Homme Patrice BLANGARIN
Localisation : France, Hérault (Languedoc Roussillon)

Informations professionnelles :
Activité : Technicien Help Desk, maintenance, réseau, système et +
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2006
Messages : 2 613
Points : 3 724
Points : 3 724
Petite modification de votre client par rapport au serveur : A vous de trouver pourquoi 'UP' n'est pas envoyé dans ce cas
Code :
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
 
##### CLIENT TCP #####
 
import socket
import tkinter as tk
 
HOTE = 'localhost' 
PORT = 12345 
TAILLE_MAX_PAQUET = 100
up = False
down = False
left = False
right = False
msg_a_envoyer = ''
 
 
sCli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sCli.connect((HOTE, PORT)) 
print("Connexion établie avec le serveur sur le port", PORT)
#############################################
 
from tkinter import *
 
root2 = Tk()
fenetre_plateau=Canvas(root2, width="487", height="315")
#photo = PhotoImage(file="mapcouper.gif")
#fenetre_plateau.create_image(243.5, 157.5, image=photo)
fenetre_plateau.pack()
 
 
 
carrebleu = [[11,94], [53,94], [11,207], [53,207]]
carrebleu2 = [[438,92], [478,92], [438,206], [478,206]]
x = 240
y = 145
r = 8
dx = 0
dy = 0
couleur="red"
msg_a_envoyer = None
 
 
def move(event):
    x = fenetre_plateau.canvasx(event.x)
    y = fenetre_plateau.canvasy(event.y)
    #if (carrebleu2[0][0] < event.x < carrebleu2[1][0] and carrebleu2[0][1] < event.y < carrebleu2[2][1]) or (carrebleu[0][0] < event.x < carrebleu[1][0] and carrebleu[0][1] < event.y < carrebleu[2][1]):
 
 
def cercle():
    return fenetre_plateau.create_oval(210, 210, 230, 230, fill=couleur,tag = "pion")
 
def up (event=None):
    global dx
    global dy
    global msg_a_envoyer
    msg_a_envoyer = 'UP' 
    dx = 0
    dy = -1
 
def down (event=None):
    global dx
    global dy
    global msg_a_envoyer
    msg_a_envoyer = 'DOWN'
    dx = 0
    dy = 1
 
def left (event=None):
    global dx
    global dy
    global msg_a_envoyer
    msg_a_envoyer = 'LEFT'
    dx = -1
    dy = 0
 
def right (event=None):
    global dx
    global dy
    global msg_a_envoyer
    msg_a_envoyer = 'RIGHT'
    dx = 1
    dy = 0
 
 
cercle()
 
root2.bind('<1>', move)
root2.bind('<Up>', up)
root2.bind('<Down>', down)
root2.bind('<Left>', left)
root2.bind('<Right>', right)
 
 
 
 
 
###################################################
 
while 1:
    fenetre_plateau.move("pion", dx,dy)
    fenetre_plateau.update()
    fenetre_plateau.after(10)
    # Saisie du message
 
 
    # Envoi du message
    if msg_a_envoyer in ('UP', 'DOWN', 'LEFT', 'RIGHT'):
        envoi = bytes(msg_a_envoyer, encoding="utf-8")
        sCli.send(envoi)
        msg_recu = sCli.recv(TAILLE_MAX_PAQUET) # octets, donc 
        recu = str(msg_recu, encoding="utf-8")  #  à encoder...
        print(recu)
        msg_a_envoyer = ''
 
    #########################################################
fen.mainloop()
Edit : Vous remarquerez aussi les ralentissement du GUI du client si vous laissez appuyer une touche par rapport au serveur. D’où l’intérêt de séparer réseau et GUI.
__________________
Merci d'utiliser le forum pour les questions techniques.
PauseKawa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2013, 13h48   #6
PauseKawa
Expert Confirmé
 
Avatar de PauseKawa
 
Homme Patrice BLANGARIN
Technicien Help Desk, maintenance, réseau, système et +
Inscription : juin 2006
Messages : 2 613
Détails du profil
Informations personnelles :
Nom : Homme Patrice BLANGARIN
Localisation : France, Hérault (Languedoc Roussillon)

Informations professionnelles :
Activité : Technicien Help Desk, maintenance, réseau, système et +
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2006
Messages : 2 613
Points : 3 724
Points : 3 724
Attention aux noms des objets : def up(event=None): / up = False etc...
Code :
1
2
3
4
5
6
7
8
>>> up = False
>>> def up():
...     pass
... 
>>> if up:
...     print('ok')
... 
ok
__________________
Merci d'utiliser le forum pour les questions techniques.
PauseKawa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2013, 16h41   #7
bromy
Invité régulier
 
Homme
Lyceen
Inscription : novembre 2012
Messages : 28
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Lyceen
Secteur : Service public

Informations forums :
Inscription : novembre 2012
Messages : 28
Points : 5
Points : 5
Citation:
Envoyé par PauseKawa Voir le message
Petite modification de votre client par rapport au serveur : A vous de trouver pourquoi 'UP' n'est pas envoyé dans ce cas
Code :
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
 
##### CLIENT TCP #####
 
import socket
import tkinter as tk
 
HOTE = 'localhost' 
PORT = 12345 
TAILLE_MAX_PAQUET = 100
up = False
down = False
left = False
right = False
msg_a_envoyer = ''
 
 
sCli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
sCli.connect((HOTE, PORT)) 
print("Connexion établie avec le serveur sur le port", PORT)
#############################################
 
from tkinter import *
 
root2 = Tk()
fenetre_plateau=Canvas(root2, width="487", height="315")
#photo = PhotoImage(file="mapcouper.gif")
#fenetre_plateau.create_image(243.5, 157.5, image=photo)
fenetre_plateau.pack()
 
 
 
carrebleu = [[11,94], [53,94], [11,207], [53,207]]
carrebleu2 = [[438,92], [478,92], [438,206], [478,206]]
x = 240
y = 145
r = 8
dx = 0
dy = 0
couleur="red"
msg_a_envoyer = None
 
 
def move(event):
    x = fenetre_plateau.canvasx(event.x)
    y = fenetre_plateau.canvasy(event.y)
    #if (carrebleu2[0][0] < event.x < carrebleu2[1][0] and carrebleu2[0][1] < event.y < carrebleu2[2][1]) or (carrebleu[0][0] < event.x < carrebleu[1][0] and carrebleu[0][1] < event.y < carrebleu[2][1]):
 
 
def cercle():
    return fenetre_plateau.create_oval(210, 210, 230, 230, fill=couleur,tag = "pion")
 
def up (event=None):
    global dx
    global dy
    global msg_a_envoyer
    msg_a_envoyer = 'UP' 
    dx = 0
    dy = -1
 
def down (event=None):
    global dx
    global dy
    global msg_a_envoyer
    msg_a_envoyer = 'DOWN'
    dx = 0
    dy = 1
 
def left (event=None):
    global dx
    global dy
    global msg_a_envoyer
    msg_a_envoyer = 'LEFT'
    dx = -1
    dy = 0
 
def right (event=None):
    global dx
    global dy
    global msg_a_envoyer
    msg_a_envoyer = 'RIGHT'
    dx = 1
    dy = 0
 
 
cercle()
 
root2.bind('<1>', move)
root2.bind('<Up>', up)
root2.bind('<Down>', down)
root2.bind('<Left>', left)
root2.bind('<Right>', right)
 
 
 
 
 
###################################################
 
while 1:
    fenetre_plateau.move("pion", dx,dy)
    fenetre_plateau.update()
    fenetre_plateau.after(10)
    # Saisie du message
 
 
    # Envoi du message
    if msg_a_envoyer in ('UP', 'DOWN', 'LEFT', 'RIGHT'):
        envoi = bytes(msg_a_envoyer, encoding="utf-8")
        sCli.send(envoi)
        msg_recu = sCli.recv(TAILLE_MAX_PAQUET) # octets, donc 
        recu = str(msg_recu, encoding="utf-8")  #  à encoder...
        print(recu)
        msg_a_envoyer = ''
 
    #########################################################
fen.mainloop()
Edit : Vous remarquerez aussi les ralentissement du GUI du client si vous laissez appuyer une touche par rapport au serveur. D’où l’intérêt de séparer réseau et GUI.
Si l'on separe le reseau de l'interface Graphique, cela resoudrait completement les problemes de decalage du mouvement ?
bromy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2013, 15h34   #8
wiztricks
Expert Confirmé Sénior
 
Inscription : juin 2008
Messages : 3 697
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 3 697
Points : 4 526
Points : 4 526
Citation:
Envoyé par bromy Voir le message
Si l'on separe le reseau de l'interface Graphique, cela resoudrait completement les problemes de decalage du mouvement ?
Dans le code initial, vous faites un appel à .move toutes les 10ms.
Côté serveur, çà attend 50ms la réception d'une nouvelle connextion puis encore 50ms secondes la réception d'un message.
Enfin, çà poste un .move à faire dans 10ms: si côté serveur les appels à .move se font toutes les 100ms, çà se déplace 10 fois moins vite.

Le gros soucis est que le serveur "attend" un changement de direction. Comme le déplacement sur les clients et le serveur sont "asynchrones", je ne vois pas comment ce qui sera affiché côté "serveur" pourra être "fidèle" à ce qui se passe côté clients.

Il serait plus "simple" de faire que les clients expédient la position "courante" à intervalles réguliers et que le "serveur" fasse des ".move" à partir de là.

Séparer réseau et interface graphique permet de construire et tester chaque partie (réseau, graphique) indépendamment l'une de l'autre. Il n'est pas indispensable de mettre la partie réseau dans un thread séparé. Mais comme vous ne savez pas trop où vous voulez aller, le coût est raisonnable.

- W
__________________
Architectures Post-Modernes
wiztricks est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2013, 19h01   #9
PauseKawa
Expert Confirmé
 
Avatar de PauseKawa
 
Homme Patrice BLANGARIN
Technicien Help Desk, maintenance, réseau, système et +
Inscription : juin 2006
Messages : 2 613
Détails du profil
Informations personnelles :
Nom : Homme Patrice BLANGARIN
Localisation : France, Hérault (Languedoc Roussillon)

Informations professionnelles :
Activité : Technicien Help Desk, maintenance, réseau, système et +
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2006
Messages : 2 613
Points : 3 724
Points : 3 724
Bonsoir wiztricks,

Citation:
Envoyé par wiztricks Voir le message
Il serait plus "simple" de faire que les clients expédient la position "courante" à intervalles réguliers et que le "serveur" fasse des ".move" à partir de là.
N'est il pas plus logique que cela soit le serveur qui donne la position ? Le 'client' n'est là que pour modifier la 'trajectoire' dans le code d'origine (voir les binds du serveur + les send).
Cela impliquerais qu'il n'y est de move sur le client 'que' par rapport aux coordonnées reçues et affiner le timing réseau / que les temps d'attentes soit égaux des deux cotés.

Citation:
Envoyé par wiztricks Voir le message
Séparer réseau et interface graphique permet de construire et tester chaque partie (réseau, graphique) indépendamment l'une de l'autre. Il n'est pas indispensable de mettre la partie réseau dans un thread séparé. Mais comme vous ne savez pas trop où vous voulez aller, le coût est raisonnable.
Est ce a dire que vous préconisez de gérer la partie de code réseau avec le mainloop ?
Cela implique que les temps d'attentes soit égaux des deux cotés.

@+
__________________
Merci d'utiliser le forum pour les questions techniques.
PauseKawa est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2013, 20h04   #10
wiztricks
Expert Confirmé Sénior
 
Inscription : juin 2008
Messages : 3 697
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 3 697
Points : 4 526
Points : 4 526
Salut PauseKawa,

Citation:
Envoyé par PauseKawa Voir le message
N'est il pas plus logique que cela soit le serveur qui donne la position ? Le 'client' n'est là que pour modifier la 'trajectoire' dans le code d'origine (voir les binds du serveur + les send).
C'est pas une question de logique mais de cas d'utilisation: que fait le serveur? que feront les clients?
Pour l'instant, pas grand chose pour décider.
J'ai l'impression que le serveur aura pour fonction de "broadcaster" les changements de position des "clients" - un peu comme un "chat" -.
A côté de ces "broadcasts", il faudrait réaliser: ajout d'un jouer, une gestion des jeux, des commandes de type request/response.

Si c'est le cas, le choix de la techno. réseau utilisée sera sans doute à revoir.
Ceci dit, c'est un projet "scolaire".

On peut espérer que les enseignants l'encadrent un peu pour limiter les fonctionnalités plutôt que de laisser les élèves partir dans tous les sens et en sortir "frustrés": faire un jeu réseau avec un display graphique sans plan ni bibliothèques qui machent un peu le boulot et "cachent" les difficultés me semble "irresponsable".

Citation:
Est ce a dire que vous préconisez de gérer la partie de code réseau avec le mainloop ? Cela implique que les temps d'attentes soit égaux des deux cotés
Je ne le préconise pas: c'est trop "sportif" pour des débutants.
Mais "techniquement", pousser la partie réseau dans un thread n'est pas indispensable.
Avec les threads, réseau et interface graphique sont deux activités "asynchrones". Le asynchrone est nécessaire pour gérer les attentes et les timeouts côté réseau en gardant "fluide" l'interface graphique.

Ceci dit une écriture réseau n'attend pas la lecture côté récepteur pour redonner la main à l'appelant du .send(sd, buffer). Et il n'est pas utile de "bloquer" forever lorsqu'il n'y a rien à lire: les messages non lus "attendront"
d'être lus, dans la pile côté récepteur.

L'interface graphique pouvant lire et écrire "sans délais" pas besoin d'avoir des activités "asynchrones". Coder cela demande une certaine expérience des "features" de la programmation avec les "sockets".
Les threads "simplifient" grandement cela et "forcent" à séparer/tester indépendamment: ce qui est "mieux" même si on peut "techniquement" s'en passer.

- W
__________________
Architectures Post-Modernes
wiztricks est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2013, 20h51   #11
bromy
Invité régulier
 
Homme
Lyceen
Inscription : novembre 2012
Messages : 28
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Lyceen
Secteur : Service public

Informations forums :
Inscription : novembre 2012
Messages : 28
Points : 5
Points : 5
Je suis un peu perdu x) Il y a pas mal de vocabulaire que je ne connais pas.

Autre chose, le projet n'est pas encadree par les profs, et c'est ca qui est mal fait.

En gros, eux ils font leurs cours d'informatique et science du numerique, et nous on fait notre projet avec les connaissances apprises.

Concretement, vous nous conseillez de nous y prendre comment au final ?
bromy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/02/2013, 11h34   #12
wiztricks
Expert Confirmé Sénior
 
Inscription : juin 2008
Messages : 3 697
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 3 697
Points : 4 526
Points : 4 526
Citation:
Envoyé par bromy Voir le message
Concretement, vous nous conseillez de nous y prendre comment au final ?
Commencez par décrire en français les fonctionnalités de votre jeu sur une ou deux pages. Puis essayez de voir comment les réaliser (toujours en français).

Citation:
nous on fait notre projet avec les connaissances apprises.
Si vous n'avez pas appris la programmation d'un GUI, réseau, threads,... çà ne sera pas "facile". Le problème est que vous devrez rendre votre copie un jour ou l'autre et que le temps que vous aller pouvoir passer à coder est compté.

Une fois que vous aurez décrit le quoi/comment (en français) il sera peut être intéressant d'aller en discuter avec vos profs pour voir s'ils peuvent vous aider un peu.

- W
__________________
Architectures Post-Modernes
wiztricks est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 08h54.


 
 
 
 
Partenaires

Hébergement Web