Page 1 sur 1
Problèmes réseau
Publié : sam. 15/déc./2007 16:17
par Oliv
Bonjour,
j'ai un petit problème avec le réseau. Je souhaiterai faire une sorte de proxy pour une application qui ne fait que du HTTP sur un site. Je pensais donc qu'il me suffirai de recopier ce qui m'était envoyé par le client sur le serveur et inversement. Mais ça ne se passe pas comme pévu, ça marche avec google par exemple, mais dès qu'il y a de gros fichiers, ça ne fonctionne plus. Est-ce que je m'y prends mal avec ce code ?
Sinon la fonction SendNetworkData() me retourne de temps en temps -1, je suppose que c'est qu'elle n'a pas pu envoyer les data, peut-on savoir pourquoi ?
Le retour de cette fonction n'est plus documenté, c'est toujours la taille envoyée si correct, -1 sinon ?
Code : Tout sélectionner
If InitNetwork() = 0
MessageRequester("Erreur", "Initialisation du réseau impossible.", #MB_ICONERROR)
End
EndIf
;- Declarations
; Constantes
Enumeration
EndEnumeration
; Structures
Structure S_Serveur
Event.l
ClientID.l
NB_Connectes.l
Adresse.s
EndStructure
Structure S_Client
Event.l
ClientID.l
EndStructure
; Listes
; Buffer
; Variables
Sortie.b
Port.l = 80
*Buffer.l = AllocateMemory(60000)
ClientID.l
Taille.l
Serveur.S_Serveur
Serveur\Adresse = "www.google.fr"
Client.S_Client
Eol.s = Chr(13) + Chr(10)
; Création du serveur
If CreateNetworkServer(0, Port) = 0
MessageRequester("Erreur", "Impossible de créer le serveur," + Eol + "le port '" + Str(Port) + "' est-il libre ?", #MB_ICONERROR)
End
EndIf
;- Création de la fenêtre
OpenWindow(0, 0, 0, 800, 600, "Test", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
StringGadget(0,0,0,800,500,"",#ES_MULTILINE|#WS_VSCROLL)
CreateStatusBar(0, WindowID(0))
AddStatusBarField(800)
StatusBarText(0, 0, "Connectés : " + Str(NB_Connectes), #PB_StatusBar_Center)
If OpenFile(0,"debug.txt")
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
Sortie = 1
EndSelect
Serveur\Event = NetworkServerEvent()
If Serveur\Event
Serveur\ClientID = EventClient()
Select Serveur\Event
Case #PB_NetworkEvent_Connect
Serveur\NB_Connectes + 1
StatusBarText(0, 0, "Nabaztag connectés : " + Str(Serveur\NB_Connectes), #PB_StatusBar_Center)
Client\ClientID = OpenNetworkConnection(Serveur\Adresse, 80)
Case #PB_NetworkEvent_Data ;- Reception de données
Taille = ReceiveNetworkData(Serveur\ClientID, *Buffer, 60000)
SendNetworkData(Client\ClientID, *Buffer, Taille)
Debug ""
Debug "Envoi"
Debug PeekS(*Buffer)
Debug "______________"
Debug ""
WriteString(0,"Envoi" + Eol)
WriteData(0,*Buffer,Taille)
WriteString(0,Eol + "______________" + Eol + Eol + Eol)
Case #PB_NetworkEvent_Disconnect
Serveur\NB_Connectes - 1
StatusBarText(0, 0, "Nabaztag connectés : " + Str(Serveur\NB_Connectes), #PB_StatusBar_Center)
CloseNetworkConnection(Client\ClientID)
EndSelect
EndIf
If Client\ClientID
Client\Event = NetworkClientEvent(Client\ClientID)
If Client\Event = #PB_NetworkEvent_Data
Taille = ReceiveNetworkData(Client\ClientID, *Buffer, 60000)
tmp = SendNetworkData(Serveur\ClientID, *Buffer, Taille)
Debug "Retour: " + Str(tmp) + "taille : " + Str(taille)
Debug PeekS(*buffer)
Debug "__________"
WriteString(0,"Retour: " + Str(tmp) + " taille : " + Str(taille) + Eol)
WriteData(0,*Buffer,Taille)
WriteString(0,Eol + "______________" + Eol + Eol + Eol)
EndIf
EndIf
Delay(50)
Until Sortie = 1
EndIf
FreeMemory(*Buffer)
Publié : dim. 16/déc./2007 23:06
par Anonyme
je n'ai pas pb sur cette station , je ne pourrais donc t'aider concretement. en revanche , si j'ai bien compris , ton appli envois et recois des fichiers plus ou moins volumineux ?
si c'est le cas , alors je te conseille de découper les fichiers envoyés , tu les découpent en plusieurs parties puis tu envois les parties une par une. même en tcp/ip tu peut avoir des pertes de paquets, donc si c'est un enorme fichier , il y aura certainement des "trous" si tu l'envois d'un coup.
Voici comment je ferais :
- J'examine le fichier a envoyé , je note la taille totale du fichier.
- je divise cette taille totale par n pour avoir des morceau d'une taille x
- j'envois un premier message contenant les infos ( nombre de parties, taille des parties )
- le client connait désormais , le nombre et la taille des parties qu'il va recevoir.
- le serveur peut envoyé la sauce.
- si le client recois une partie d'une taille inferieure ou supérieur , tu renvois cette partie. tu peut aussi à la rigueur "taggé" les parties , un tag pour le début , et un pour la fin. tu extraits ce qu'il y a entre les tags pour récupérer les données.
@++
Publié : dim. 16/déc./2007 23:56
par Oliv
Je me suis mal exprimmé
En fait les "gros fichiers" sont des fichiers d'environ 60Ko, mais ce problème là est résolu : il fallait mettre un delay() dans la boucle d'envoi, car je saturais le destinataire...
En fait mon but est de faire un proxy http, qui n'a besoin de relayer que les commandes 'GET'. J'ai refait un peu le code aujourd'hui en plus propre, mais ça ne fonctionne toujours pas correctement, et je n'arrive pas à trouver pourquoi.....
Code : Tout sélectionner
If CreateFile(0,"Debug_Proxy.txt")
If InitNetwork() = 0
MessageRequester("Erreur", "Initialisation du réseau impossible.", #MB_ICONERROR)
End
EndIf
;- ********** Declarations ************************
; Constantes
#Max = 1
#T_Buffer_R_Nabaz = 2000
Enumeration
EndEnumeration
; Structures
Structure S_Serveur
Event.l
Port.l
EndStructure
Structure S_Client
ID.l
*Buffer.l
Taille.l
Commande.s
Cookie.s
Accept.s
Host.s
ContentType.s
ContentLength.s
Adresse.s
Connexion.l
Port.s
EndStructure
; Listes
NewList Clients.S_Client()
; Variables
Sortie.b
Define.l i, Length
Serveur.S_Serveur
Define.s Eol, Temp
;- ********** Initialisations ****************
; Serveur
Serveur\Port = 4444
; Autres
Eol = Chr(13) + Chr(10)
; Création du serveur
If CreateNetworkServer(0, Serveur\Port) = 0
MessageRequester("Erreur", "Impossible de créer le serveur," + Eol + "le port '" + Str(Port) + "' est-il libre ?", #MB_ICONERROR)
End
EndIf
;- ********** Fonctions ******************
;- ********** Création de la fenêtre *************
OpenWindow(0, 0, 0, 800, 600, "Nabaztag", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
Sortie = 1
Case #PB_Event_Gadget
Select EventGadget()
EndSelect
EndSelect
Serveur\Event = NetworkServerEvent()
If Serveur\Event
Select Serveur\Event
Case #PB_NetworkEvent_Connect
AddElement(Clients())
Clients()\ID = EventClient()
Clients()\Buffer = AllocateMemory(#T_Buffer_R_Nabaz)
WriteStringN(0,"Nouveau client connecté, ClientID : " + Str(Clients()\ID))
Case #PB_NetworkEvent_Disconnect
WriteStringN(0,"Un client c'est déconnecté, ClientID : " + Str(EventClient()))
ResetList(Clients())
While NextElement(Clients())
If Clients()\ID = EventClient()
If Clients()\Connexion
CloseNetworkConnection(Clients()\Connexion)
EndIf
FreeMemory(Clients()\Buffer)
DeleteElement(Clients())
Break
EndIf
Wend
Case #PB_NetworkEvent_Data
FillMemory_(Clients()\Buffer, #T_Buffer_R_Nabaz, 0)
ResetList(Clients())
While NextElement(Clients())
If Clients()\ID = EventClient()
Clients()\Taille = ReceiveNetworkData(Clients()\ID, Clients()\Buffer, #T_Buffer_R_Nabaz)
If PeekS(Clients()\Buffer,3) = "GET" ; Si on reçoit la commande 'GET'
; On détermine le header envoyé
Clients()\Accept = ""
Clients()\Host = ""
Clients()\Cookie = ""
Clients()\ContentType = ""
Clients()\ContentLength = ""
Clients()\Commande = StringField(PeekS(Clients()\Buffer,Clients()\Taille),1,Eol)
For i = 1 To CountString(PeekS(Clients()\Buffer,Clients()\Taille),Eol) + 1
Temp = StringField(PeekS(Clients()\Buffer,Clients()\Taille),i,Eol)
If FindString(Temp,"Accept: ",1) : Clients()\Accept = Temp : EndIf
If FindString(Temp,"Host: ",1) : Clients()\Host = Temp : EndIf
If FindString(Temp,"Cookie: ",1) : Clients()\Cookie = Temp : EndIf
If FindString(Temp,"Content-Type: ",1) : Clients()\ContentType = Temp : EndIf
If FindString(Temp,"Content-Length: ",1) : Clients()\ContentLength = Temp : EndIf
Next i
WriteStringN(0,"--- Commande reçue ---")
WriteStringN(0,Clients()\Commande)
WriteStringN(0,"Accept: [" + Clients()\Accept + "]")
WriteStringN(0,"Host: [" + Clients()\Host + "]")
WriteStringN(0,"Cookie: [" + Clients()\Cookie + "]")
WriteStringN(0,"Content-Type: [" + Clients()\ContentType + "]")
WriteStringN(0,"Content-Length: [" + Clients()\ContentLength + "]")
WriteStringN(0,"---")
; On récupère le contenu du champ 'Host' pour s'y connecter
Clients()\Adresse = Right(Clients()\Host, Len(Clients()\Host) - 6)
Clients()\Port = StringField(Clients()\Adresse,2,":")
If Clients()\Port = "" : Clients()\Port = "80" : EndIf
Clients()\Adresse = StringField(Clients()\Adresse,1,":")
Clients()\Adresse = RemoveString(Clients()\Adresse, " ")
WriteStringN(0,"Adresse : " + Clients()\Adresse + " | Port : " + Clients()\Port)
WriteStringN(0,"")
Clients()\Connexion = OpenNetworkConnection(Clients()\Adresse,Val(Clients()\Port))
; Construction de la commande 'GET' à envoyer au serveur
FillMemory_(Clients()\Buffer, #T_Buffer_R_Nabaz, 0)
Clients()\Commande = RemoveString(Clients()\Commande,":80")
Debug Clients()\Commande
Length = PokeS(Clients()\Buffer, Clients()\Commande + Eol)
If Clients()\Host : Length + PokeS(Clients()\Buffer + Length, Clients()\Host + Eol) : EndIf
Length + PokeS(Clients()\Buffer + Length, "User-Agent: ONabz-Proxy/1.0" + Eol)
If Clients()\Cookie : Length + PokeS(Clients()\Buffer + Length, Clients()\Cookie + Eol) : EndIf
If Clients()\Accept : Length + PokeS(Clients()\Buffer + Length, Clients()\Accept + Eol) : EndIf
Length + PokeS(Clients()\Buffer + Length, "Connection: close" + Eol)
WriteStringN(0,"--- Get construit ---")
WriteStringN(0,PeekS(Clients()\Buffer))
WriteStringN(0,"")
; On se connecte au serveur
If Clients()\Connexion
SendNetworkData(Clients()\Connexion, Clients()\Buffer, Length)
Else
WriteStringN(0,"Impossible de se connecter au serveur.")
WriteStringN(0,"")
EndIf
Else
Debug "Pas GET..."
EndIf
Break
EndIf
Wend
EndSelect
EndIf
ResetList(Clients())
While NextElement(Clients())
If Clients()\Connexion
If NetworkClientEvent(Clients()\Connexion)
Repeat
FillMemory_(Clients()\Buffer, #T_Buffer_R_Nabaz, 0)
Clients()\Taille = ReceiveNetworkData(Clients()\Connexion, Clients()\Buffer, #T_Buffer_R_Nabaz)
tmp.l = SendNetworkData(Clients()\ID, Clients()\Buffer, Clients()\Taille)
Debug WSAGetLastError_()
If tmp = -1 : Debug "--- Retour de -1 ---" : Debug WSAGetLastError_() : EndIf
Delay(250)
Until Clients()\Taille < #T_Buffer_R_Nabaz
WriteStringN(0,"--- Données reçues ---")
WriteStringN(0,Str(Clients()\Taille))
WriteStringN(0,"")
EndIf
EndIf
Wend
Delay(50)
Until Sortie = 1
CloseFile(0)
Else
Debug "Impossible d'ouvrir"
EndIf
End
Publié : lun. 17/déc./2007 0:17
par Anonyme
je ne peut pas tester le code , trop d'api W32.
les Delay() me paraissent énorme tout de même , 250ms a mon humble avis est de trop , un delay de 75 suffirait largement. et le delay(50) , c'est inutile , tu freezes le programme. essaye les threads.
Publié : lun. 17/déc./2007 1:40
par Oliv
Ah oui pardon

Cette version est sans API WIN32 (compilée sous MacOS)
Code : Tout sélectionner
If InitNetwork() = 0
MessageRequester("Erreur", "Initialisation du réseau impossible.")
End
EndIf
;- ********** Declarations ************************
; Constantes
#Max = 1
#T_Buffer_R_Nabaz = 2000
Enumeration
EndEnumeration
; Structures
Structure S_Serveur
Event.l
Port.l
EndStructure
Structure S_Client
ID.l
*Buffer.l
Taille.l
Commande.s
Cookie.s
Accept.s
Host.s
ContentType.s
ContentLength.s
Adresse.s
Connexion.l
Port.s
EndStructure
; Listes
NewList Clients.S_Client()
; Variables
Sortie.b
Define.l i, Length
Serveur.S_Serveur
Define.s Eol, Temp
;- ********** Initialisations ****************
; Serveur
Serveur\Port = 4444
; Autres
Eol = Chr(13) + Chr(10)
; Création du serveur
If CreateNetworkServer(0, Serveur\Port) = 0
MessageRequester("Erreur", "Impossible de créer le serveur," + Eol + "le port '" + Str(Port) + "' est-il libre ?")
End
EndIf
;- ********** Fonctions ******************
Procedure FillMemory(*Buffer.l,Taille.l,Car.l)
For i.l = 0 To Taille-1
PokeL(*Buffer + i, Car)
Next i
EndProcedure
Serveur\Event
If CreateFile(0,"Debug_Proxy.txt")
;- ********** Création de la fenêtre *************
OpenWindow(0, 0, 0, 800, 600, "Nabaztag", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
Sortie = 1
Case #PB_Event_Gadget
Select EventGadget()
EndSelect
EndSelect
Serveur\Event= NetworkServerEvent()
If Serveur\Event
Select Serveur\Event
Case 1
AddElement(Clients())
Clients()\ID = EventClient()
Clients()\Buffer = AllocateMemory(#T_Buffer_R_Nabaz)
WriteStringN(0,"Nouveau client connecté, ClientID : " + Str(Clients()\ID))
Case 4
WriteStringN(0,"Un client c'est déconnecté, ClientID : " + Str(EventClient()))
ResetList(Clients())
While NextElement(Clients())
If Clients()\ID = EventClient()
If Clients()\Connexion
CloseNetworkConnection(Clients()\Connexion)
EndIf
FreeMemory(Clients()\Buffer)
DeleteElement(Clients())
Break
EndIf
Wend
Case 2
FillMemory(Clients()\Buffer, #T_Buffer_R_Nabaz, 0)
ResetList(Clients())
While NextElement(Clients())
If Clients()\ID = EventClient()
Clients()\Taille = ReceiveNetworkData(Clients()\ID, Clients()\Buffer, #T_Buffer_R_Nabaz)
If PeekS(Clients()\Buffer,3) = "GET" ; Si on reçoit la commande 'GET'
; On détermine le header envoyé
Clients()\Accept = ""
Clients()\Host = ""
Clients()\Cookie = ""
Clients()\ContentType = ""
Clients()\ContentLength = ""
Clients()\Commande = StringField(PeekS(Clients()\Buffer,Clients()\Taille),1,Eol)
For i = 1 To CountString(PeekS(Clients()\Buffer,Clients()\Taille),Eol) + 1
Temp = StringField(PeekS(Clients()\Buffer,Clients()\Taille),i,Eol)
If FindString(Temp,"Accept: ",1) : Clients()\Accept = Temp : EndIf
If FindString(Temp,"Host: ",1) : Clients()\Host = Temp : EndIf
If FindString(Temp,"Cookie: ",1) : Clients()\Cookie = Temp : EndIf
If FindString(Temp,"Content-Type: ",1) : Clients()\ContentType = Temp : EndIf
If FindString(Temp,"Content-Length: ",1) : Clients()\ContentLength = Temp : EndIf
Next i
WriteStringN(0,"--- Commande reçue ---")
WriteStringN(0,Clients()\Commande)
WriteStringN(0,"Accept: [" + Clients()\Accept + "]")
WriteStringN(0,"Host: [" + Clients()\Host + "]")
WriteStringN(0,"Cookie: [" + Clients()\Cookie + "]")
WriteStringN(0,"Content-Type: [" + Clients()\ContentType + "]")
WriteStringN(0,"Content-Length: [" + Clients()\ContentLength + "]")
WriteStringN(0,"---")
; On récupère le contenu du champ 'Host' pour s'y connecter
Clients()\Adresse = Right(Clients()\Host, Len(Clients()\Host) - 6)
Clients()\Port = StringField(Clients()\Adresse,2,":")
If Clients()\Port = "" : Clients()\Port = "80" : EndIf
Clients()\Adresse = StringField(Clients()\Adresse,1,":")
Clients()\Adresse = RemoveString(Clients()\Adresse, " ")
WriteStringN(0,"Adresse : " + Clients()\Adresse + " | Port : " + Clients()\Port)
WriteStringN(0,"")
Clients()\Connexion = OpenNetworkConnection(Clients()\Adresse,Val(Clients()\Port))
; Construction de la commande 'GET' à envoyer au serveur
FillMemory(Clients()\Buffer, #T_Buffer_R_Nabaz, 0)
Clients()\Commande = RemoveString(Clients()\Commande,":80")
Debug Clients()\Commande
Length = PokeS(Clients()\Buffer, Clients()\Commande + Eol)
If Clients()\Host : Length + PokeS(Clients()\Buffer + Length, Clients()\Host + Eol) : EndIf
Length + PokeS(Clients()\Buffer + Length, "User-Agent: ONabz-Proxy/1.0" + Eol)
If Clients()\Cookie : Length + PokeS(Clients()\Buffer + Length, Clients()\Cookie + Eol) : EndIf
If Clients()\Accept : Length + PokeS(Clients()\Buffer + Length, Clients()\Accept + Eol) : EndIf
Length + PokeS(Clients()\Buffer + Length, "Connection: close" + Eol)
WriteStringN(0,"--- Get construit ---")
WriteStringN(0,PeekS(Clients()\Buffer))
WriteStringN(0,"")
; On se connecte au serveur
If Clients()\Connexion
SendNetworkData(Clients()\Connexion, Clients()\Buffer, Length)
Else
WriteStringN(0,"Impossible de se connecter au serveur.")
WriteStringN(0,"")
EndIf
Else
Debug "Pas GET..."
EndIf
Break
EndIf
Wend
EndSelect
EndIf
ResetList(Clients())
While NextElement(Clients())
If Clients()\Connexion
If NetworkClientEvent(Clients()\Connexion)
Repeat
FillMemory(Clients()\Buffer, #T_Buffer_R_Nabaz, 0)
Clients()\Taille = ReceiveNetworkData(Clients()\Connexion, Clients()\Buffer, #T_Buffer_R_Nabaz)
tmp.l = SendNetworkData(Clients()\ID, Clients()\Buffer, Clients()\Taille)
If tmp = -1 : Debug "--- Retour de -1 ---" : EndIf
Delay(250)
Until Clients()\Taille < #T_Buffer_R_Nabaz
WriteStringN(0,"--- Données reçues ---")
WriteStringN(0,Str(Clients()\Taille))
WriteStringN(0,"")
EndIf
EndIf
Wend
Delay(50)
Until Sortie = 1
CloseFile(0)
Else
Debug "Impossible d'ouvrir"
EndIf
End
Publié : lun. 17/déc./2007 11:16
par Anonyme
cela fonctionne sous linux , mais je ne comprends pas l'utilisation
ta un code de client qui fait fonctionné ton serveur ?
Publié : lun. 17/déc./2007 17:25
par Oliv
En fait quand le serveur répond, tout n'est pas toujours transmis correctement. J'ai vu un exemple de proxy sur le forum Allemand aujourd'hui, apparement ils ont le même problème....
Publié : lun. 17/déc./2007 19:44
par Anonyme
tu numérotes les données envoyé par le client ou par le serveur, si l'un des programmes reçois les données numéro 3 sans avoir reçu la numéro 2 , alors tu renvois la n°2 ,
Publié : lun. 17/déc./2007 19:52
par Oliv
Oui mais non

Je n'ai pas accès aux données.
En fait (j'aurais du commencer par là), j'ai un
Nabaztag, c'est une déco sympathique, mais gadget vite limité, même avec l'API fournie. Donc je veux lui faire un "proxy", qui lui envoie directement des informations car les possiblitées deviennent beaucoup plus grandes, mais qui relaie aussi celles qui lui sont "vitales" envoyées par les serveurs de la sociéte qui le vend.
Je sais que c'est possible car quelqu'un l'a fait en PHP, mais j'y omprends rien et PB est plus souple pour ce que je veux faire....
Publié : mar. 18/déc./2007 10:01
par Ar-S
Tu veux lui faire un "proxy" ?
je ne pige pas trop là ce que tu veux dire par proxy.
Publié : mar. 18/déc./2007 10:18
par Oliv
En fait je dis proxy car je ne connais pas le terme exact
Je veux faire un serveur qui capte tout ce que le Nabaztag émet, puis transmet les commandes que je veux au serveurs de la société, il faut donc gérer les retours faits par la société pour les renvoyer sur le Nabaztag. C'est à ce moment que ça coince, j'ai l'impression que tout n'est pas renvoyé correctement.
De cette manière, je pourrais envoyer des ordres bien plus rapidement (la société ne met à jour les ordres pour le Nabaztag que toutes les deux minutes)
Pour le problème de transmission de données, j'ai trouvé hier sur le forum Allemand un code d'un proxy qui était construit comme le mien et avait les même défauts..... J'ai du mal avec l'Allemand mais les auteurs n'ont pas eu l'air de trouver d'où ça venait.
Publié : mar. 18/déc./2007 13:54
par Anonyme
Donc , c'est ton programme , qui a des soucis d'envois , ton lapin ne reçois pas tout si j'ai bien compris. le problème peut venir du lapin , car d'appli a appli , ca fonctionne super. peut être qui a des spécification a respecter concernant la fréquence d'envois ?
essaye de changer de protocole ( en UDP ) ?
Publié : mar. 18/déc./2007 17:12
par Oliv
Cpl.Bator a écrit :Donc , c'est ton programme , qui a des soucis d'envois , ton lapin ne reçois pas tout si j'ai bien compris. le problème peut venir du lapin , car d'appli a appli , ca fonctionne super. peut être qui a des spécification a respecter concernant la fréquence d'envois ?
essaye de changer de protocole ( en UDP ) ?
Tout est fait en HTTP, donc le protocole est TCP
Bon problème est mal situé en fait, j'arrives à envoyer au lapin du stream mp3 donc je pense que la façon dont j'envoie les données au lapin est bonne, mais pour tout ce qui est renvoyé par les serveurs de Violet...ça e fonctionne pas et je ne sais pas du tout d'où ça vient.