def manageClient(self, connection): global writingTurn client = self.get_client_by_connection_id( connection) #identify client data try: request_bits = self.readMessage(client) # read the cryptic message request = Request(request_bits, cipher) # form the request object #(this processes the cryptic message and makes it a easy to read dictionary) #the client/server comunicates using json format request_code = request.body()[ "code"] #each action has a different code if request_code == 1: #set preferred_mode client.data.update( {"preferred_mode": request.body()["data"]["mode"]}) client.data.update({"step": 1}) res = Response({"code": "Ok"}, cipher) client.connection.send(res.len()) client.connection.send(res._encode()) if request_code == 2: #ask for chosen mode if self.all_clients_chose_preferred_mode( ): # if it's ready send KEY, IV, MODE, if not tell to wait and ask later chosen_mode = self.get_chosen_mode() client_iv = None key = None if chosen_mode == "CFB": client_iv = iv.decode('utf-8') key = k2.decode('utf-8') else: key = k1.decode('utf-8') res = Response( { "code": "Ready", # create the response with all necessary data "data": { "chosen_mode": chosen_mode, "iv": client_iv, "key": key, "comunication_role": client.data["comunication_role"] } }, cipher) client.connection.send(res.len()) client.connection.send(res._encode()) else: res = Response({"code": "Not Ready"}, cipher) client.connection.send(res.len()) client.connection.send(res._encode()) if request_code == 3: # client informs that it has finished it's job writing/reading 8 blocks client.data.update({"hasFinished": True}) if self.all_clients_have_finished(): for cl in self.clients_list: cl.data.update({"canContinue": True}) res = Response({"code": "Ok"}, cipher) client.connection.send(res.len()) client.connection.send(res._encode()) if request_code == 4: # client asks for permission to continue sending/reading next 8 blocks if client.data.get( "comunication_role" ) == THE_READER: #here I have implemented a sort of a semaphore if writingTurn: res = Response({"code": "Not Ready"}, cipher) client.connection.send(res.len()) client.connection.send(res._encode()) writingTurn = True return else: if client.data.get("canContinue", None) == True: client.data.update({"canContinue": False}) client.data.update({"hasFinished": False}) res = Response({"code": "Yes"}, cipher) writingTurn = True client.connection.send(res.len()) client.connection.send(res._encode()) else: res = Response({"code": "Not Ready"}, cipher) client.connection.send(res.len()) client.connection.send(res._encode()) if client.data.get("comunication_role") == THE_WRITER: if not writingTurn: res = Response({"code": "Not Ready"}, cipher) client.connection.send(res.len()) client.connection.send(res._encode()) return else: if client.data.get("canContinue", None) == True: client.data.update({"canContinue": False}) client.data.update({"hasFinished": False}) res = Response({"code": "Yes"}, cipher) writingTurn = False client.connection.send(res.len()) client.connection.send(res._encode()) else: res = Response({"code": "Not Ready"}, cipher) client.connection.send(res.len()) client.connection.send(res._encode()) except Exception as e: print(e) exit()