[Borland C++] Socket qui modifie les données ...

Socket qui modifie les données ... [Borland C++] - C++ - Programmation

Marsh Posté le 17-01-2006 à 17:40:44    

:hello:  
 
Je develloppe une petite application de type puissance 4, en reseau (TCP/IP), avec borland C++ 6.
 
Pour le moment le serveur est le client sont sur la meme machine, et ils s'echangent un tableau d'entier "tab[6][7]".
 
Jusque là, tout va bien, je fait des send et recv auparavant pour le login, ... tout fonctionne bien. Par contre, dès que j'envoie ce tableau, aux endroits ou j'ai joué, il me modifie le contenu (les pions du joueur == 1, ceux du pc == 2)
 
Exemple de mes fichiers de log :
coté client

17h 33m 08s 250ms : click sur le bouton envoyer
17h 33m 08s 250ms : Le joueur a joué en tab[0][0] = 1
17h 33m 09s 062ms : (Apres envoi)Le joueur a joué en tab[0][0] = 1
17h 33m 10s 671ms : (Avant reception)Le joueur a joué en tab[0][0] = 1
17h 33m 10s 671ms : Anomalie en tab[0][0] = 16777216
17h 33m 10s 671ms : Anomalie en tab[1][0] = 33554432
17h 33m 10s 671ms : (Apres reception)Le joueur a joué en tab[0][0] = 16777216
17h 33m 12s 281ms : (fin de la methode)Le joueur a joué en tab[0][0] = 16777216


 
coté server

17h 33m 09s 062ms : 1 -> le serveur reçoit le tableau du client panda et le teste
17h 33m 09s 062ms : Info dans tab[0][0] : 1  
17h 33m 09s 062ms : le serveur joue dans tab[1][0] = 2
17h 33m 09s 062ms : le serveur à joué dans tab[1][0] = 2 et va tester
17h 33m 09s 062ms : le serveur envoie son tableau au client panda : tab[1][0] = 2
17h 33m 09s 062ms : avant envoi : tab[1][0] = 2  
17h 33m 09s 062ms : Info dans tab[0][0] : 1  
17h 33m 09s 062ms : apres envoi : tab[1][0] = 2  
17h 33m 09s 062ms : Info dans tab[0][0] : 1  
17h 33m 09s 062ms : le serveur a envoyé son tableau au client panda : tab[1][0] = 2


 
C'est assez étrange  :??:  
 
Si vous voulez des bouts de code, ou les programmes complets, dite-le, je ne les mets pas directement pour + de lisibilité.
 
MErci de m'aider  :hello:  
 


---------------
.
Reply

Marsh Posté le 17-01-2006 à 17:40:44   

Reply

Marsh Posté le 17-01-2006 à 18:17:44    

tu dois avoir un problème d'ordre des octets poids forts/poids faible car  
16777216 = 0x01000000 et 33554432 = 0x02000000
 
les données ne sont pas transmises/lues de la même manière entre le serveur et le client.

Message cité 1 fois
Message édité par fat le 17-01-2006 à 18:19:43
Reply

Marsh Posté le 17-01-2006 à 18:23:22    

fat a écrit :

tu dois avoir un problème d'ordre des octets poids forts/poids faible car  
16777216 = 0x01000000 et 33554432 = 0x02000000
 
les données ne sont pas transmises/lues de la même manière entre le serveur et le client.


 
Interessant :)
 
Mais les revc / send sont identiques dans les 2 applications
client

Code :
  1. recv(SockStream,(char*)&tabJeu,sizeof(tabJeu),0);
  2. send(SockStream,(char*)&tabJeu,sizeof(tabJeu),0)


 
serveur

Code :
  1. recv(NewSocket,(char*)&tabcli,sizeof(tabcli),0)
  2. send(NewSocket,(char*)&tabcli,sizeof(tabcli),0)


---------------
.
Reply

Marsh Posté le 17-01-2006 à 18:36:52    

Si c'est sur le meme ordi, normalement y pas de difference entre poid faible et fort ..Il peut y avoir un probleme d'alignement si les donnees que tu envois sont differemment structurees ou les options de compil differentes pour l'alignement.
 
 

Reply

Marsh Posté le 17-01-2006 à 19:13:47    

francky06l a écrit :

Si c'est sur le meme ordi, normalement y pas de difference entre poid faible et fort ..Il peut y avoir un probleme d'alignement si les donnees que tu envois sont differemment structurees ou les options de compil differentes pour l'alignement.


 
Merci te ton aide, mais je crois que je suis un peu bloqué la, ce sont les memes données : int tab[6][7];, et je compile sans rien changer, donc je suppose qu'il ne change pas des options aléatoirement  :sweat:  
 
Je vais essayer de reprendre une ancienne version, et de repartir de la


---------------
.
Reply

Marsh Posté le 17-01-2006 à 20:06:06    

didier1809 a écrit :

Code :
  1. recv(SockStream,(char*)&tabJeu,sizeof(tabJeu),0);
  2. send(SockStream,(char*)&tabJeu,sizeof(tabJeu),0)



Sont indispensables les & devant tabJeu ?
 
A mon avis fat tiens le bon bout. Tu es sûr qu'il n'y a pas une transformation little/big endian quelque part ?

Message cité 1 fois
Message édité par slash33 le 17-01-2006 à 20:08:45
Reply

Marsh Posté le 17-01-2006 à 20:37:29    

slash33 a écrit :

Sont indispensables les & devant tabJeu ?
 
A mon avis fat tiens le bon bout. Tu es sûr qu'il n'y a pas une transformation little/big endian quelque part ?


 
Pas indispensables, mais ca ne change pas grand chose, j'ai les memes résultats avec et sans.
 
Pour la trasformation litle/big, c'est bien possible, j'ai tellement d'ondes négatives avec Borland qu'il me fait peut être ca :D
 
Plus sérieusement, mon tableau n'est modifié qu'avec des instructions du style tab[i][j] = 2;
 
Vous voulez les sources ?


---------------
.
Reply

Marsh Posté le 17-01-2006 à 23:33:13    

c'est effectivement bizzare, vu que c'est sur le même machine et que les fonction d'écriture/lecture sont correcte, je ne vois pas trop.
par contre à ta place je ne mettrai pas le & devant le tabJeu.
 
S'il y a un problème d'alignement, tu devrais avoir d'autres valeurs incorrectes (si bien sur il y a d'autres valeurs non nulles) dans ton tableau.
 
essaie en mettant des valeurs particulières dans le tableau et regarde ce que tu obtiens de l'autre coté.
 
par exemple tabJeu={
{0x1,0x2,0x4,0x8,0x10,0x20,0x40},
{0x10,0x20,0x40,0x80,0x100,0x200,0x400},
{0x100,0x200,0x400,0x800,0x1000,0x2000,0x4000},
{0x1000,0x2000,0x4000,0x8000,0x10000,0x20000,0x40000},
{0x10000,0x20000,0x40000,0x80000,0x100000,0x200000,0x400000},
{0x100000,0x200000,0x400000,0x800000,0x1000000,0x2000000,0x4000000},
{0x1000000,0x2000000,0x4000000,0x8000000,0x10000000,0x20000000,0x40000000},
}
 
 
Tu peux aussi essaye de voir ce que ca donne si tu déclare ton tableau comme un tableau de char plutot que de int


Message édité par fat le 17-01-2006 à 23:34:25
Reply

Marsh Posté le 18-01-2006 à 00:14:10    

Il a FORCEMENT une inversion d'octets maintenant pour savoir d'où elle provient...
 
"Plus sérieusement, mon tableau n'est modifié qu'avec des instructions du style tab[i][j] = 2;"
Le problème ne doit pas être dans l'affectation directe du tableau.
 
"Vous voulez les sources ?"
Je crois que c'est nécessaire en effet.

Message cité 1 fois
Message édité par slash33 le 18-01-2006 à 00:16:15
Reply

Marsh Posté le 18-01-2006 à 06:53:59    

slash33 a écrit :

Il a FORCEMENT une inversion d'octets maintenant pour savoir d'où elle provient...
 
"Plus sérieusement, mon tableau n'est modifié qu'avec des instructions du style tab[i][j] = 2;"
Le problème ne doit pas être dans l'affectation directe du tableau.
 
"Vous voulez les sources ?"
Je crois que c'est nécessaire en effet.


 
http://home.tiscali.be/didier1809/Client.rar
http://home.tiscali.be/didier1809/Serveur.rar
 
 :jap:


---------------
.
Reply

Marsh Posté le 18-01-2006 à 06:53:59   

Reply

Marsh Posté le 18-01-2006 à 10:00:31    

tes fichiers rar ne sont pas bons : entete du fichier corrompu
Et pour alleger la taille des fichier rar, tu peux ne pas mettre dedans les fichiers .tds (utilisé par le debugger) et .obj

Message cité 1 fois
Message édité par fat le 18-01-2006 à 10:03:01
Reply

Marsh Posté le 18-01-2006 à 10:39:09    

fat a écrit :

tes fichiers rar ne sont pas bons : entete du fichier corrompu
Et pour alleger la taille des fichier rar, tu peux ne pas mettre dedans les fichiers .tds (utilisé par le debugger) et .obj


 
Merci,problème de type de transfert ftp ;)
 
Voici les bons :
http://home.tiscali.be/didier1809/Client.tar.gz
http://home.tiscali.be/didier1809/Serveur.tar.gz


---------------
.
Reply

Marsh Posté le 18-01-2006 à 10:49:22    

Heu y'a deux fichiers Client : Client.cpp et Client2.cpp lequel est le bon?
 
Edit: ah OK vu.

Message cité 1 fois
Message édité par slash33 le 18-01-2006 à 10:51:03
Reply

Marsh Posté le 18-01-2006 à 10:52:16    

slash33 a écrit :

Heu y'a deux fichiers Client : Client.cpp et Client2.cpp lequel est le bon?
 
Edit: ah OK vu.


 
J'ai pas compris la logique du borland la dessus, mais bon ...  
 
Ca doit être programmé n'importe comment, désolé  :o Mais je ne me fait pas à cette programmation  :(


---------------
.
Reply

Marsh Posté le 18-01-2006 à 11:57:13    

J'ai trouvé ton problème, ce n'est pas une problème d'inversion d'octets mais de décalage.
ton serveur lorsqu'il accepte le mot de passe, renvoi un int
mais du coté du client, on va lire un bool qui lui ne fait que 1 octet, ce qui fait qu'il reste 3 octets ( des 00) dans la socket.
Ensuite le client envoie le tableau, qui est bien reçu coté serveur,  
par contre quand le serveur le renvoi et que le client va le lire sur la socket, il va lire d'abord les 3 octets qui trainaient là depuis l'acceptation du mot de passe, d'où un décalage de 3 octets, et après lecture, il reste alors encore 3 octets du tableau dans la socket, qui ne seront lu que la fois d'après.
 
Pour éviter ce genre de désagrément, il faudrait mettre au point un petit protocole de transmission entre le serveur et le client, quelque chose de simple du genre :
un octet pour indiquer l'action : envoi mot de passe/reception reponse au mot depasse, envoi tableau, j'ai gagné, fin du jeu
deux octets pour indiquer le nombre d'octets (N) qui suivent
N octets formant les données à transmettre
en faisant cela, tu restera synchrone entre l'envoi et la reception.
quand tu lis les données, tu lis 1 octet puis 2 octets et ensuite tu lis les N octets qui suivent
comme vérification tu peux vérifier que le premier octet corresponds bien à un code action  
 
 
autre remarque, dans les fonction TestXXXX, à part dans TestHorizontal où tu teste la valeur 1 dans le tableau, dans les autres TestXXXXX, tu teste une valeur <> 0, ce qui fait qu'il confonds les pièces jouées par le serveur et celles jouées par le client, et donc dire que al grille est gagnante alors qu'elle ne l'est pas.
tu pourrais par exemple donner en paramètre à ces fonction la valeur à tester (1 ou 2), soit sous forme d'int ou de bool (serveur ou client)
 
Enfin pour terminer, si tu utilisais vraiment les particularités de borland c++, cela te simplifierais enormément le boulot, notamment pour l'utilisation des socket.
regarde dans les exemples fournis avec BCB, ily a un exemple qui s'apelle "chat".
 
 
 
EDIT : afin d'obtenir un exe distribuable seul, qui n' pas besoin d'autres dll/fichiers, il faut décocher "Utiliser la RTL dynamique" dans l'onglet Lieur dans les options du projet, et également la case "construire avec les paquets d'execution" dans l'onglet Paquets

Message cité 1 fois
Message édité par fat le 18-01-2006 à 12:05:24
Reply

Marsh Posté le 18-01-2006 à 11:59:07    

Super intéressante l'idée :love:

Reply

Marsh Posté le 18-01-2006 à 12:10:43    

fat a écrit :

J'ai trouvé ton problème, ce n'est pas une problème d'inversion d'octets mais de décalage.
ton serveur lorsqu'il accepte le mot de passe, renvoi un int
mais du coté du client, on va lire un bool qui lui ne fait que 1 octet, ce qui fait qu'il reste 3 octets ( des 00) dans la socket.


Le seul coin du code que je n'ai pas regardé... :sweat:  
 

fat a écrit :

Pour éviter ce genre de désagrément, il faudrait mettre au point un petit protocole de transmission entre le serveur et le client, quelque chose de simple du genre :
un octet pour indiquer l'action : envoi mot de passe/reception reponse au mot depasse, envoi tableau, j'ai gagné, fin du jeu
deux octets pour indiquer le nombre d'octets (N) qui suivent
N octets formant les données à transmettre
en faisant cela, tu restera synchrone entre l'envoi et la reception.
quand tu lis les données, tu lis 1 octet puis 2 octets et ensuite tu lis les N octets qui suivent
comme vérification tu peux vérifier que le premier octet corresponds bien à un code action


Exact. Fait très récemment sur le modèle TLV (type, longueur, valeur) des protocoles de communication réseau.
 
Mais dis moi fat, tu as debuggé son programme sous Borland ou tu as juste analysé les sources (ce que j'ai essayé de faire) ?

Message cité 1 fois
Message édité par slash33 le 18-01-2006 à 12:40:14
Reply

Marsh Posté le 18-01-2006 à 12:43:47    

slash33 a écrit :


Mais dis moi fat, tu as debuggé son programme sous Borland ou tu as juste analysé les sources (ce que j'ai essayé de faire) ?


 
Je l'ai débuggé sous borland, le serveur et le client en même temps dans deux instances de borland, le tableau était transmis correctement au serveur mais c'est quand le serveur le renvoie au client qu'il y avait problème. j'ai pensé alors à des octets qui pouvaient trainer. j'ai alors regardé ce qui se passait avant.

Reply

Marsh Posté le 18-01-2006 à 12:47:17    

Effectivement, avec le debugger c'est plus facile... :o  
 

fat a écrit :

c'est quand le serveur le renvoie au client qu'il y avait problème.


Ben oui ça se voyait dans ses journaux de log.
Bon l'important c'est d'avoir trouvé (et de lui demander de refaire avec le framework qui convient!  :lol: )


Message édité par slash33 le 18-01-2006 à 12:49:54
Reply

Marsh Posté le 18-01-2006 à 16:34:45    

Un énorme merci !
 
Je pouvais chercher encore longtemps :o, surtout que c'est un travail pour un cours, et que'on travaille en binome, je ne me suis pas occupé des points qui clochent  :ange:  
 
Pour les utilisations des sockets, c'est notre prof qui travaille comme ca, je ne vais pas le contrarier :D
 
Je posterai les sources finaux ici, au cas ou :)
 
Encore merci :)


---------------
.
Reply

Marsh Posté le 18-01-2006 à 16:46:51    

En gros un probleme d'alignement ...:-)

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed