Closed david540 closed 7 years ago
Et j'ai aussi eu quelques fois des IA qui étaient déconnecté du serveur en pleine partie sans raison: File "C:\Users\David\Desktop\Bourse_reseau\clientLastVersion.py", line 133, in __recevoir raise RuntimeError("Connexion perdu. _5") RuntimeError: Connexion perdu. _5
ok une réseau pour la déconnection des clients est surement ça :
File "C:\Users\David\Desktop\Bourse_reseau\clientLastVersion.py", line 356, in ventes
return eval(self.__recevoir())
File "
C'est la longueur de mes ventes qui font des messages réseaux énormes, déjà on pourrait ignorer les ventes supérieur à 25 euros et les achats inférieurs à 0.25 non ? Ensuite je ne sais pas si ça va réellement être possible de lister tous les achats et ventes, peut être plutôt les 20 meilleurs ?
J'ai modifié en gardant que les 20 meilleurs, j'ai résolu l'une des erreur mais pas celle là java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source) at java.util.AbstractCollection.toString(Unknown Source) at java.lang.String.valueOf(Unknown Source) at network.Client.run(Client.java:137)
Une fois qu'une exception non gérée est levée par le serveur, il s'arrête complètement. Essaie d'ajouter le nom clé synchronized dans les méthodes core.Marche::getListeAchats et core.Marche::getListeVentes pour voir si cela résout le problème.
Pour la longueur de la requête est-ce que tu pourrais me donner sa taille ? (en nombre de caractère)
Pour ce qui est de lister les 20 meilleurs, c'est justement la contribution suivante :
Néanmoins, j'aimerais qu'il soit tout de même possible de tout récupérer en gardant r.ventes('Facebook').
L'exception vient du fait que tu essaies, à la fois, de lire les ventes et d'écrire dessus. Synchronized devrait résoudre le problème, sinon je le ferrai avec un mutex.
J'ai ajouté les Synchronized et j'ai surchargé la fonction getListeVentes, on appelle la première si la longueur demandée est trop grande ou inférieur ou égale à 0 et la deuxième sinon (pour pas qu'il y est d'erreur avec le sublist et pour ne pas faire de cast si on veut toute la liste)
public synchronized Set
Client déconnecté
at java.util.TreeMap$PrivateEntryIterator.nextEntry(Unknown Source)
at java.util.TreeMap$KeyIterator.next(Unknown Source)
at java.util.AbstractCollection.finishToArray(Unknown Source)
at java.util.AbstractCollection.toArray(Unknown Source)
at java.util.LinkedList.addAll(Unknown Source)
at java.util.LinkedList.addAll(Unknown Source)
at java.util.LinkedList.
Cette exception déconnecte seulement le client mais pas le serveur
J'ai revu le système de concurrence des threads (9d82199e3f4eca2121c2475aa1381964ffca5c2a). Tu peux essayer avec cette nouvelle version.
Si j'ai bien suivi, les exceptions serveurs sont résolues #14.
Par contre, ça m'intéresserait de savoir si en utilisant r.achats(actions) sans limiter la taille, tu arrives encore à déclencher l'exception client que tu décris dans ton commentaire 3. Et si c'est le cas, quelle est la taille de la chaîne reçu (supérieur à 99999999 ?)?
Oui il y a encore un problème si la liste est trop grande J'ai mis un print(len(back.decode())) pour suivre la taille des chaines reçus Deux des clients ont eu une exception vers 2800 caractère et un autre vers 3800 donc il n'y a pas l'air d'avoir de limite. Au faite je ne l'avais pas dis mais l'erreur est un SyntaxError: EOL while scanning string literal et qui apparait quand les chaines sont très grandes.
La seconde exception devrait être fixée par ces modifications : (83feb994eeae9925d498f2b734d4b6f7f536c5d4). Tu peux re-sync. Est-ce bien le cas?
Non malheureusement ça n'a pas résolu le problème, voici l'exception complète côté client (il n'y a aucune erreur détectée côté serveur):
Traceback (most recent call last):
File "C:\Users\David\Desktop\Bourse_reseau\IAorganise.py", line 135, in
Je me suis trompé lors du merge. Mon code a été effacé. Tu peux re-sync et essayer (28249524fb2c8587ba4635f97cf9d7022bb7dc01).
J'avais déjà copié collé ce nouveau __recevoir(), J'ai eu une erreur EOF cette fois SyntaxError: unexpected EOF while parsing
Est-ce que tu pourrais me donner le code minimal permettant de reproduire le bug à coup sur ?
Oui je vais essayer d'en faire un, Le problème vient peut être du OutputStreamWriter::out.write(packet) J'ai lu qu'il y avait une taille max de 8192 caractères et quand je remplace le out.write(packet) par out.write(packet,0,500) quand packet.size()>500 j'ai le même type d'erreur (mais beaucoup plus tôt) ça n'expliquerait pas par contre pourquoi il y a ce problème à seulement 3000 caractères s'il vient de ça
C'était le cas avec le BufferedWriter, c'est pour ça que j'ai changé à OutputStreamWriter. Si la taille est plus grande que celle d'un paquet TCP, plusieurs paquets seront envoyés. Je ne pense pas que ce soit le serveur java qui ajoute un caractère EOL ou EOF.
Est-ce que tu peux essayer de lancer tes scripts sur le serveur officiel ? Pour voir si tu as aussi des exceptions. J'ai l'impression que ça pourrait venir du système d'exploitation. Sous Linux (serveur et client), je n'ai pas de problème même avec des requêtes de taille supérieur à 60 000 bytes.
C'est bon je pense avoir résolu le problème, en poursuivant l'idée que vous avez eu pour la lecture côté client.py, j'ai mis ça: int compteur=0,keep=packet.length(); while(keep>1000){ out.write(packet,1000compteur,1000(compteur+1)); out.flush(); compteur++; keep=packet.length()-(1000compteur); } out.write(packet,1000compteur,packet.length()); out.flush(); Et maintenant ça marche
Ah non je n'ai rien dis, le serveur a levé une exception Je vais essayer sur le serveur officiel alors
Oui même problème avec le serveur officiel ^ SyntaxError: EOL while scanning string literal
Il me faudrait un code minimal pour que je puisse reproduire l'erreur de mon côté.
from client import Reseau from random import*
r=Reseau("localhost",23456)
pseudo="Bot"+str(int(random()100)) cle=25670#A changer pour chaque partie while r.rejoindrePartie(cle,pseudo)<0: pseudo="Bot"+str(int(random()100)) r.top() while int(r.fin()['temps'])>0: r.bid("Facebook",1,1) r.ventes("Facebook")
Il faut créer la partie manuellement, mettre la clé de la partie dans le code puis lancer 5 shells avec ce programme
Effectivement chez moi il y a un ajout d'un EOL ou EOF tout seul, avec ce code ça marche :
def __recevoir(self):
try:
length = self.__sock.recv(8)
if length == b'':
raise RuntimeError("Connexion perdu. _5")
length=int(length.decode())
result=''
while True:
keep = length - len(result)
if keep > 4096:
back = self.__sock.recv(4096)
if back == b'':
raise RuntimeError("Connexion perdu. _3")
result += back.decode()
else:
back = self.__sock.recv(keep)
if back == b'':
raise RuntimeError("Connexion perdu. _6")
result += back.decode()
break
result=result[:len(result)-1] #On supprime le dernier caractere de la str temporaire
return result
Ca vient de client.py mais si les systèmes d'exploitations gèrent ça différemment ça va être compliqué, un test if (result[-1] == 'EOF' or result[-1] == 'EOL'): result=result[:-1] à la fin de la boucle while True ?
Non je me suis trompé c'était pas ça le problème, là ça marche tout le temps
def __recevoir(self):
try:
length = self.__sock.recv(8)
if length == b'':
raise RuntimeError("Connexion perdu. _5")
length=int(length.decode())
result=''
while True:
keep = length - len(result)
if keep > 4096:
back = self.__sock.recv(4096)
if back == b'':
raise RuntimeError("Connexion perdu. _3")
result += back.decode()
else:
back = self.__sock.recv(keep)
if back == b'':
raise RuntimeError("Connexion perdu. _6")
result += back.decode()
if length == len(result): # ICI sinon des fois il y a break sans que le client ait lu tout le message du client, si les parties du messages du client n'ont pas pour taille 4096
break
return result
except (ConnectionRefusedError):
raise RuntimeError("Connexion perdu. _4")
Dans certains cas, la découpe ne doit peut être pas se faire tout les 4096 bytes, le problème venait de là je crois, le break était call sans que tout le message soit reçu
Félicitations, il n'a pas été simple à trouver.
Après avoir lancé 2 IA sur un serveur local (qui font énormément de demandes serveur), j'ai eu ce message d'erreur:
java.util.ConcurrentModificationException at java.util.TreeMap$PrivateEntryIterator.nextEntry(Unknown Source) at java.util.TreeMap$KeyIterator.next(Unknown Source) at java.util.AbstractCollection.toString(Unknown Source) at java.lang.String.valueOf(Unknown Source) at network.Client.run(Client.java:137)
ça ressemble à un problème de threads non ? Après cette exception mes IA ont encore fait quelques demandes, puis plus rien, les IA ne sont plus avertis que la partie et fini et quand l'hôte fait un del(r), le serveur n'affiche pas "Client déconnecté" et les IA ne reçoivent toujours pas de messages d'erreurs les IA reçoivent un message d'erreur seulement quand je déconnecte le serveur