Bonjour a tous cela fait déjà quelque mois que j'arrive a me débrouiller sans vous mais la je bloque...

J'ai créer un combo Client/Serveur lien vers un de mes anciens poste pour le detail. Le probleme c'est pour quitter le client je doit pour le moment fermer purment et simplement le terminal donc pas moyen d'indiquer au client d'envoyer un message au serveur afin d'indiquer ça déconnexion. J'ai put comprendre grace a mes recherche que dans ce types de situations socket envoyait un signal mais je ne sais pas comment le recuperer(via un .receiv?) ni a quoi il ressemble. Actuellement le serveur n’écoute que une fois le client lors de l'initialisation du thread puis ne fait que parler, lui client ne fait lui que écouter .Créer un 2e thread d’écoute pourrait être catastrophique niveau perf étant donne que j'ai pour ambition de tenir plusieurs centaine de client en même temps (pour le moment une trentaine, plus m’empêchant de voir mon écran).

Existe il un code if blablabla alors socket.close qui pourrais s'executer dans ma boucle while ? de plus comment fermer "proprement" le thread un fois la detection de la deconexion du client? et comment compter le nombre de thread (resolue, threading.active_count() )?

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
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
import socket
import time
 
hote = "localhost"
port = 15555
reponse = "none"
Wait_Check = 3
Mode = 1        #1 mode slave, 2 mode leader.
link = False
tentative = 1
Service_Enable = [1,1,1,1] #[S1, S2, S3, S4] -> 1 enable, 0 disable
 
 
#---------------------------------------------------------------------------------------
 
 
print("Connection...")
 
while link == False:
 
        try:
                socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                socket.connect((hote, port))
                print ("Connecter")
                link = True
        except:
                print("Erreur de connection")
 
        tentative += 1
        time.sleep(tentative%5)
 
 
 
                #----------------------------------------------#
if Mode == 1:
        socket.send(str("__update_global/"+str(Wait_Check)+"/"+str(Mode)+"/").encode())
        reponse = socket.recv(2048)
        print("Reponse: ", str(reponse).split("'",2)[1])
 
        while reponse != " __leave ":
 
                reponse = socket.recv(2048)
                print("Reponse: ", str(reponse).split("'",2)[1])
 
 
 
                #----------------------------------------------#
else:
        socket.send(str("__update_global/"+str(Wait_Check)+"/"+str(Mode)+"/").encode())
        reponse = socket.recv(2048)
        print("Reponse: ", str(reponse).split("'",2)[1])
 
        while link == True:
 
                if len(reponse) == 0:
                    # La connexion est perdue
                    link = False
                    socket.close() 
                else:
                    # Traiter la donnée reçue
                    socket.send(str("__update/S1"+"/").encode())
 
 
print ("Deconnexion")
socket.close()
Serveur:
(La partie qui nous intéressent commence a la ligne ~122)

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
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
import socket
import threading
import time
from tkinter import *
 
#-------------------------------------------------------------------------------------#
 
def Etat_0_S1():
 
    Etat_S1.set("Bon")
    info_etat_S1.config(text="Etat du reseau: Aucun probleme connue")
    print("Update S1", Etat_S1.get())
 
 
def Etat_1_S1():
 
    Etat_S1.set("Moyen")
    info_etat_S1.config(text="Etat du reseau: Presence de ralentissement sur le reseau")
    print("Update S1", Etat_S1.get())
 
 
def Etat_2_S1():
 
    Etat_S1.set("Mauvais")
    info_etat_S1.config(text="Etat du reseau: Reseau indisponible")
    print("Update S1", Etat_S1.get())
 
                #-----------------------#
 
def Etat_0_S2():
 
    Etat_S2.set("Bon")
    info_etat_S2.config(text="Etat du reseau: Aucun probleme connue")
    print("Update S2", Etat_S2.get())
 
 
def Etat_1_S2():
 
    Etat_S2.set("Moyen")
    info_etat_S2.config(text="Etat du reseau: Presence de ralentissement sur le reseau")
    print("Update S2", Etat_S2.get())
 
 
def Etat_2_S2():
 
    Etat_S2.set("Mauvais")
    info_etat_S2.config(text="Etat du reseau: Reseau indisponible")
    print("Update S2", Etat_S2.get())
 
                #-----------------------#
 
def Etat_0_S3():
 
    Etat_S3.set("Bon")
    info_etat_S3.config(text="Etat du reseau: Aucun probleme connue")
    print("Update S3", Etat_S3.get())
 
 
def Etat_1_S3():
 
    Etat_S3.set("Moyen")
    info_etat_S3.config(text="Etat du reseau: Presence de ralentissement sur le reseau")
    print("Update S3", Etat_S3.get())
 
 
def Etat_2_S3():
 
    Etat_S3.set("Mauvais")
    info_etat_S3.config(text="Etat du reseau: Reseau indisponible")
    print("Update S3", Etat_S3.get())
 
                #-----------------------#
 
def Etat_0_S4():
 
    Etat_S4.set("Bon")
    info_etat_S4.config(text="Etat du reseau: Aucun probleme connue")
    print("Update S4", Etat_S4.get())
 
 
def Etat_1_S4():
 
    Etat_S4.set("Moyen")
    info_etat_S4.config(text="Etat du reseau: Presence de ralentissement sur le reseau")
    print("Update S4", Etat_S4.get())
 
 
def Etat_2_S4():
 
    Etat_S4.set("Mauvais")
    info_etat_S4.config(text="Etat du reseau: Reseau indisponible")
    print("Update S4", Etat_S4.get())
 
#-------------------------------------------------------------------------------------#
 
class ClientThread(threading.Thread):
 
    def __init__(self, ip, port, clientsocket, Etat_S1, Etat_S2, Etat_S3, Etat_S4):
 
        threading.Thread.__init__(self)
        self.ip = ip
        self.port = port
        self.clientsocket = clientsocket
        print("[+] Nouveau thread pour %s %s" % (self.ip, self.port, ))
 
    def run(self):
 
        print("Connection de %s %s" % (self.ip, self.port, ))
        link = True
        Last_choice = 0
        Last_state_S1 = "none"
        Last_state_S2 = "none"
        Last_state_S3 = "none"
        Last_state_S4 = "none"
 
        requete = self.clientsocket.recv(2048)
        print("Requete:",str(requete).split("'",2)[1])
        Wait_Check = (str(requete).split("__")[1]).split("/")[1]
        Mode = (str(requete).split("__")[1]).split("/",3)[2]
        print("Mode:",Mode,"/")
 
        if int(Mode) == 1:
            while link == True:
 
                if ((str(requete).split("__")[1]).split("/")[0] == " __update_global " and Last_choice != 1) or  Last_state_S1 != Etat_S1.get() or  Last_state_S2 != Etat_S2.get()or  Last_state_S3 != Etat_S3.get()or  Last_state_S4 != Etat_S4.get():
                    self.clientsocket.send(str("__S1:"+Etat_S1.get()+"/"+"S2:"+Etat_S2.get()+"/"+"S3:"+Etat_S3.get()+"/"+"S4:"+Etat_S4.get()+"/").encode())
                    Last_choice = 1
 
                    Last_state_S1 = Etat_S1.get()
                    Last_state_S2 = Etat_S2.get()
                    Last_state_S3 = Etat_S3.get()
                    Last_state_S4 = Etat_S4.get()
                    # __ -> debut de message, / -> separation en != information
 
                elif (requete == "__leave" and Last_choice != 2) or len(requete) == 0:
                    Last_choice = 2
                    link = False
                    self.clientsocket.close()
 
                elif Last_choice != 3 and (Last_state_S1 != Etat_S1.get() or  Last_state_S2 != Etat_S2.get()or  Last_state_S3 != Etat_S3.get()or  Last_state_S4 != Etat_S4.get()):
                    #elif permettant de gerer de futur action
                    self.clientsocket.send("autre".encode())
                    Last_choice = 3
 
                print("\n\t\t",self.ip,":",self.port,"\tS1: ",Etat_S1.get()," S2: ",Etat_S2.get()," S3: ",Etat_S3.get()," S4: ",Etat_S4.get(),"\tWait_Check: ",Wait_Check,"\tMode:",Mode)
                time.sleep(int(Wait_Check))
 
        """
        /!\ Work in progress /!\
        else:
 
            requete = self.clientsocket.recv(2048)
            if ((str(requete).split("__")[1]).split("/")[0] == " __update_global " and Last_choice != 1) or  Last_state != Etat_reseau.get():
                self.clientsocket.send(str("__S1:"+Etat_reseau.get()+"/").encode())
                Last_choice = 1
                Last_state = Etat_reseau.get()
                # __ -> debut de message, / -> separation en != information
            elif requete == "__leave" and Last_choice != 2:
                Last_choice = 2
                link = False
                self.clientsocket.close()
                
            elif Last_choice != 3 and Last_state != Etat_reseau.get():
                self.clientsocket.send("autre".encode())
                Last_choice = 3
 
 
        print("Client déconnecté...")
        """
 
#-------------------------------------------------------------------------------------#
 
class Serveur(threading.Thread):
 
    def __init__(self, Etat_S1, Etat_S2, Etat_S3, Etat_S4):
 
        threading.Thread.__init__(self)
 
    def run(self):
 
        tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        tcpsock.bind(("",15555))
 
        while True:
 
            tcpsock.listen(10)
            print( "\nEn écoute...")
            (clientsocket, (ip, port)) = tcpsock.accept()
            newthread = ClientThread(ip, port, clientsocket, Etat_S1, Etat_S2, Etat_S3, Etat_S4)
            newthread.start()
 
#-------------------------------------------------------------------------------------#
 
 
#------------#
#    Main    #
#------------#
 
fenetre_choix = Tk()
fenetre_choix.title("Panel d'administration")
fenetre_choix.configure(bg = "#00B3D7")
 
 
Etat_S1 = StringVar()
Etat_S1.set("Bon") #0: bon 1:moyen 2:mauvais
 
Etat_S2 = StringVar()
Etat_S2.set("Bon") #0: bon 1:moyen 2:mauvais
 
Etat_S3 = StringVar()
Etat_S3.set("Bon") #0: bon 1:moyen 2:mauvais
 
Etat_S4 = StringVar()
Etat_S4.set("Bon") #0: bon 1:moyen 2:mauvais
 
 
info_action = Label(fenetre_choix, text = "Action en cours: Aucune", bg = "#00B3D7")
 
Frame_Struct1 = Frame(fenetre_choix, bg = "#00B3D7")
 
Frame_S1 = LabelFrame(Frame_Struct1, text="Service 1", borderwidth=2, relief=GROOVE, bg = "#00B3D7")
button_bon1 = Button(Frame_S1, text = "Aucun probleme connue",font="arial 12 bold",command=Etat_0_S1, bg = "#33FF00", relief=FLAT)
button_moy1 = Button(Frame_S1, text = "Presence de ralentissement sur le reseau",font="arial 12 bold", command=Etat_1_S1, bg = "#FFFF00", relief=FLAT)
button_mau1 = Button(Frame_S1, text = "Reseau indisponible",font="arial 12 bold",command=Etat_2_S1, bg = "#CC0000", relief=FLAT)
info_etat_S1 = Label(Frame_S1, text = "Etat du reseau: Aucun probleme connue" , bg = "#00B3D7")
 
Frame_S2 = LabelFrame(Frame_Struct1, text="Service 2", borderwidth=2, relief=GROOVE, bg = "#00B3D7")
button_bon2 = Button(Frame_S2, text = "Aucun probleme connue",font="arial 12 bold",command=Etat_0_S2, bg = "#33FF00", relief=FLAT)
button_moy2 = Button(Frame_S2, text = "Presence de ralentissement sur le reseau",font="arial 12 bold", command=Etat_1_S2, bg = "#FFFF00", relief=FLAT)
button_mau2 = Button(Frame_S2, text = "Reseau indisponible",font="arial 12 bold",command=Etat_2_S2, bg = "#CC0000", relief=FLAT)
info_etat_S2 = Label(Frame_S2, text = "Etat du reseau: Aucun probleme connue" , bg = "#00B3D7")
 
 
Frame_Struct2 = Frame(fenetre_choix, bg = "#00B3D7")
 
Frame_S3 = LabelFrame(Frame_Struct2, text="Service 3", borderwidth=2, relief=GROOVE, bg = "#00B3D7")
button_bon3 = Button(Frame_S3, text = "Aucun probleme connue",font="arial 12 bold",command=Etat_0_S3, bg = "#33FF00", relief=FLAT)
button_moy3 = Button(Frame_S3, text = "Presence de ralentissement sur le reseau",font="arial 12 bold", command=Etat_1_S3, bg = "#FFFF00", relief=FLAT)
button_mau3 = Button(Frame_S3, text = "Reseau indisponible",font="arial 12 bold",command=Etat_2_S3, bg = "#CC0000", relief=FLAT)
info_etat_S3 = Label(Frame_S3, text = "Etat du reseau: Aucun probleme connue" , bg = "#00B3D7")
 
Frame_S4 = LabelFrame(Frame_Struct2, text="Service 4", borderwidth=2, relief=GROOVE, bg = "#00B3D7")
button_bon4 = Button(Frame_S4, text = "Aucun probleme connue",font="arial 12 bold",command=Etat_0_S4, bg = "#33FF00", relief=FLAT)
button_moy4 = Button(Frame_S4, text = "Presence de ralentissement sur le reseau",font="arial 12 bold", command=Etat_1_S4, bg = "#FFFF00", relief=FLAT)
button_mau4 = Button(Frame_S4, text = "Reseau indisponible",font="arial 12 bold",command=Etat_2_S4, bg = "#CC0000", relief=FLAT)
info_etat_S4 = Label(Frame_S4, text = "Etat du reseau: Aucun probleme connue" , bg = "#00B3D7")
 
taille_x_l = Label(fenetre_choix, bg = "#00B3D7")
taille_y_b = Label(fenetre_choix, bg = "#00B3D7")
info_ip = Label(fenetre_choix, text = "Quelle est l'etat du service ?", bg = "#00B3D7")
 
#
 
 
info_action.pack(side=TOP,pady=20)
taille_x_l.pack(side=TOP,padx=380)
info_ip.pack(side=TOP, pady = 5)
 
Frame_Struct1.pack(side = TOP, pady = 5)
 
Frame_S1.pack(side=LEFT, padx=10)
button_bon1.pack(side=TOP,padx=50,pady=10)
button_moy1.pack(side=TOP,padx=10,pady=10)
button_mau1.pack(side=TOP,padx=50,pady=10)
info_etat_S1.pack(side=TOP)
 
Frame_S2.pack(side=RIGHT, padx=10)
button_bon2.pack(side=TOP,padx=50,pady=10)
button_moy2.pack(side=TOP,padx=10,pady=10)
button_mau2.pack(side=TOP,padx=50,pady=10)
info_etat_S2.pack(side=TOP)
 
 
Frame_Struct2.pack(side = TOP)
 
Frame_S3.pack(side=LEFT, padx=10)
button_bon3.pack(side=TOP,padx=50,pady=10)
button_moy3.pack(side=TOP,padx=10,pady=10)
button_mau3.pack(side=TOP,padx=50,pady=10)
info_etat_S3.pack(side=TOP)
 
Frame_S4.pack(side=RIGHT, padx=10)
button_bon4.pack(side=TOP,padx=50,pady=10)
button_moy4.pack(side=TOP,padx=10,pady=10)
button_mau4.pack(side=TOP,padx=50,pady=10)
info_etat_S4.pack(side=TOP)
 
taille_y_b.pack(side=TOP,pady=40)
 
 
ThreadServeur = Serveur(Etat_S1, Etat_S2, Etat_S3, Etat_S4)
ThreadServeur.start()
 
fenetre_choix.mainloop()
 
 
#-------------------------------------------------------------------------------------#