Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2616 connectés 

  FORUM HardWare.fr
  Programmation
  C++

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

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

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

n°1285790
didier1809
${citation_perso}
Posté le 17-01-2006 à 17:40:44  profilanswer
 

: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:  
 


---------------
.
mood
Publicité
Posté le 17-01-2006 à 17:40:44  profilanswer
 

n°1285840
fat
Posté le 17-01-2006 à 18:17:44  profilanswer
 

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
n°1285844
didier1809
${citation_perso}
Posté le 17-01-2006 à 18:23:22  profilanswer
 

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)


---------------
.
n°1285855
francky06l
Posté le 17-01-2006 à 18:36:52  profilanswer
 

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.
 
 

n°1285891
didier1809
${citation_perso}
Posté le 17-01-2006 à 19:13:47  profilanswer
 

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


---------------
.
n°1285925
slash33
Posté le 17-01-2006 à 20:06:06  profilanswer
 

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
n°1285956
didier1809
${citation_perso}
Posté le 17-01-2006 à 20:37:29  profilanswer
 

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 ?


---------------
.
n°1286197
fat
Posté le 17-01-2006 à 23:33:13  profilanswer
 

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
n°1286213
slash33
Posté le 18-01-2006 à 00:14:10  profilanswer
 

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
n°1286244
didier1809
${citation_perso}
Posté le 18-01-2006 à 06:53:59  profilanswer
 

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:


---------------
.
mood
Publicité
Posté le 18-01-2006 à 06:53:59  profilanswer
 

n°1286306
fat
Posté le 18-01-2006 à 10:00:31  profilanswer
 

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
n°1286349
didier1809
${citation_perso}
Posté le 18-01-2006 à 10:39:09  profilanswer
 

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


---------------
.
n°1286359
slash33
Posté le 18-01-2006 à 10:49:22  profilanswer
 

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
n°1286362
didier1809
${citation_perso}
Posté le 18-01-2006 à 10:52:16  profilanswer
 

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  :(


---------------
.
n°1286440
fat
Posté le 18-01-2006 à 11:57:13  profilanswer
 

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
n°1286444
godbout
Génial.
Posté le 18-01-2006 à 11:59:07  profilanswer
 

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

n°1286453
slash33
Posté le 18-01-2006 à 12:10:43  profilanswer
 

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
n°1286486
fat
Posté le 18-01-2006 à 12:43:47  profilanswer
 

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.

n°1286492
slash33
Posté le 18-01-2006 à 12:47:17  profilanswer
 

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
n°1286747
didier1809
${citation_perso}
Posté le 18-01-2006 à 16:34:45  profilanswer
 

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 :)


---------------
.
n°1286760
francky06l
Posté le 18-01-2006 à 16:46:51  profilanswer
 

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

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

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

 

Sujets relatifs
un script qui modifie un autre scriptExtraire données Access => catalogue papier
Afficher des données d'un autre siteBesoin d'aide - Petite base de données en ligne
[Borland C++][Résolu] TListBox et ascenseurkit administration d'une base de données postgresql
Delphi - TOleEnum - Type de Données[PHP] Problème de connection à la base de données
Doublons dans base de donnéesTaille des données renvoyées après un OCIBindByName ...
Plus de sujets relatifs à : [Borland C++] Socket qui modifie les données ...


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR