Bataille Navale en réseau avec Thread

cs_lillie69 Messages postés 18 Date d'inscription lundi 27 mars 2006 Statut Membre Dernière intervention 6 mai 2006 - 4 mai 2006 à 10:22
cs_lillie69 Messages postés 18 Date d'inscription lundi 27 mars 2006 Statut Membre Dernière intervention 6 mai 2006 - 4 mai 2006 à 16:05
Bonjour,
je dois programmer une bataille navale en réseau en utilisant des threads(sous Unix)!
J'ai crée les fonctions de ma bataille navale ainsi que mon serveur et mon client!
Et en ce moment j'essaye de transférer la grille solution qui se trouve sur le serveur aux clients(pour pouvoir vérifier les coups sans devoir repasser par le serveur à chaque fois)!
Mais le problème c'est qu'il m'envois n'importe quoi,alors que si je l'affcihe dans le serveur, ma grille est correcte mais une fois qu'elle se retrouve dans mon thread c'est du n'importe quoi!!
J'ai tout essayer mais je n'arrive pas à trouver d'où vient le problème!!
Merci d'avance pour vos réponses.

Voici les partie de code:
SERVEUR
#include <stdio.h>
#include


#include
#include <sys/socket.h>
#include <sys/types.h>
#include
#include <netinet/in.h>
#include <stdint.h>
#include <string.h>


#include "socket.h"
#include "transmission.h"
#include "bateau.h"


#define NJ 2 //nombre de joueurs



typedef struct
{
int com;
char nom_joueur[30];
int grille[10][10];

} CLIENT;



void * initialisation_joueur(void* voidparam)
{



CLIENT *client=(CLIENT*) voidparam;
reception_chaine(client->com,client->nom_joueur,255);

char sms0[80]="Bienvenue ";
int i;
int compte=strlen(client->nom_joueur);
for(i=10;i<=(10+compte+1);i++)
sms0[i]=client->nom_joueur[i-10];

transmettre_chaine(client->com,sms0);



pthread_exit(0);
return NULL;
}



void * envoi_grille(void* voidparam)
{


int i,j;
CLIENT *client=(CLIENT*) voidparam;
afficher_grille(client->grille);
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
transmettre_entier(client->com,client->grille[i][j]);
}

pthread_exit(0);
return NULL;
}


int main()
{
CLIENT client[NJ];
pthread_t threads[2*NJ];
int connexion;
int port=12000;
int code;
int grille[10][10];
int i,j,k;
bateau *vaisseau[4];
initialiser_grille(client->grille);
placer_bateau_aleatoirement(client->grille,vaisseau);


//création du point de connexion
connexion= point_connexion(port);
if(connexion < 0)
return 1;

printf("attente de joueurs sur le port %d\n", port);

for(i=0;i<NJ;i++)
{
client[i].com=accept(connexion,NULL,NULL);
printf("Client connecte : %d\n", i);

}





code= pthread_create(&threads[0], NULL, initialisation_joueur, &client[0]);
code= pthread_create(&threads[1], NULL, initialisation_joueur, &client[1]);


code= pthread_create(&threads[2], NULL,envoi_grille, &client[2]);
code= pthread_create(&threads[3], NULL,envoi_grille, &client[3]);




pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
pthread_join(threads[2], NULL);
pthread_join(threads[3], NULL);


// fermeture du point de connexion
close(connexion);

printf("stop\n");


return 0;
}

CLIENT

#include <stdio.h>
#include
#include
#include <sys/socket.h>
#include <netinet/in.h>


#include "socket.h"
#include "transmission.h"
#include "bateau.h"


#define NJ 2 //nombre de joueurs



typedef struct
{
int com;
char nom_joueur[30];
int grille[10][10];

}JOUEUR;





void *lecture(void *voidparam)
{
JOUEUR *joueur=(JOUEUR*) voidparam;
char chaine[255];
int code;
code=reception_chaine(joueur->com, chaine, 255);
if(code <= 0)
;
printf("%s\n",chaine);
pthread_exit(0);
return NULL;
}



void *ecriture(void *voidparam)
{
JOUEUR *joueur=(JOUEUR*) voidparam;
char chaine[255];
int code;
scanf("%s",chaine);
code= transmettre_chaine(joueur->com, chaine);
if(code <= 0)
;
pthread_exit(0);
return NULL;
}





void *reception_grille(void *voidparam)
{
JOUEUR *joueur=(JOUEUR*) voidparam;
int i,j;

for(i=0;i<10;i++)
{

for(j=0;j<10;j++)
joueur->grille[i][j]=reception_entier(joueur->com);
}
pthread_exit(0);
return NULL;
}


int main()
{
JOUEUR *joueur;
int port=12000;
int grille[10][10];
initialiser_grille(grille);
Case * c;
c=(Case *)malloc(sizeof(Case) *1);
pthread_t threads[4];

printf("Quel est votre prenom? \n");

joueur->com= canal_communication("localhost", port);


if(joueur->com < 0)
return 1;




pthread_create(&threads[0], NULL, lecture, (void *) &(joueur->com));
pthread_create(&threads[1], NULL, ecriture, (void *) &(joueur->com));
pthread_create(&threads[2], NULL, reception_grille, (void *) &(joueur));


pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
pthread_join(threads[2], NULL);



close(joueur->com);

printf("stop\n");

return 0;
}

16 réponses

cs_laurent1024 Messages postés 987 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 30 août 2012 25
4 mai 2006 à 11:05
Salut
Verifie le fonctionnement d'envoi d'un entier. Je sais pas comment tu le gere mais par exemple si tu l'envoit en chaine de caractere et que tu envoit 1 puis 5 le client verra 15 et non 1 et 5
++
0
cs_lillie69 Messages postés 18 Date d'inscription lundi 27 mars 2006 Statut Membre Dernière intervention 6 mai 2006
4 mai 2006 à 11:21
Je pense pas que ca vienne de ca car au lieu d'avoir des 0,1,2,3 ou 4 je me retrouve avec des -1208751 ou des nombres dans ce style la!
Mais voici quand même ma fonction de transmission d'entier:

int transmettre_entier(int communication, int entier)
{

int code;
uint32_t nn;


// convertir l'entier au format reseau

nn= htonl(entier);


// transmettre l'entier
code= write(communication, &nn, sizeof(nn));
if(code < 0)
// erreur de transmission
return code;
return nn;
}



int reception_entier(int communication)
{
int n;
int code;
uint32_t nn;


// recevoir un entier au format reseau
code= read(communication, &nn, sizeof(nn));
if(code < sizeof(nn))
// reception incomplete
return -1;


// convertir en entier
n= ntohl(nn);
return n;
}

Merci pour la réponse
0
cs_lillie69 Messages postés 18 Date d'inscription lundi 27 mars 2006 Statut Membre Dernière intervention 6 mai 2006
4 mai 2006 à 11:27
Petite précision sur mon problème: en fait quand je fais afficher ma grille dans le main du serveur, celle-ci est correcte. Par contre si je fais afficher ma grille au tout début du thread envoi_grille, avant même qu'il l'ai transmise, et bien il n'affiche pas la même grille que celle qui se trouve dans le main, comme si je lui passé pas la bonne grille en paramètre et donc qu'il me mettait n'importe quel chiffre!
Mais j'ai beau chercher je ne comprends pas pourquoi il me fait ca, alors je me demandais s'il n'y avait pas un problème avec le 4e paramètre de mes pthread_create?

Merci
0
cs_laurent1024 Messages postés 987 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 30 août 2012 25
4 mai 2006 à 11:37
#define NJ 2
CLIENT client[NJ];
code= pthread_create(&threads[2], NULL,envoi_grille, &client[2]);<- client[2] doit pas existe
code= pthread_create(&threads[3], NULL,envoi_grille, &client[3]); <- pareil pour client3
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_lillie69 Messages postés 18 Date d'inscription lundi 27 mars 2006 Statut Membre Dernière intervention 6 mai 2006
4 mai 2006 à 11:52
Effectivement il ne devait pas exister, j'ai donc rajouter CLIENT client[2*NJ];
mais ca ne marche toujours pas, enfin c'est bizare car sur environ 1/4 de ma grille j'ai des 0 ou des 1 mais il reste toujours des chiffres qui ne correspondent à rien.
0
cs_laurent1024 Messages postés 987 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 30 août 2012 25
4 mai 2006 à 11:55
De plus, ta fonction pour initialiser la grille, a priori (a vérifier) , initialise que client->grille donc client[0] mais les les autres grilles (clients[1] ..... )
0
cs_lillie69 Messages postés 18 Date d'inscription lundi 27 mars 2006 Statut Membre Dernière intervention 6 mai 2006
4 mai 2006 à 12:29
Oh merci beaucoup, en effet j'initialisais que le 1er client!!
J'ai donc rajouté une boucle for pour initialiser tous mes clients et ca marche sauf que il ne prend plus en compte "placer_bateau_aleatoirement"!
Il faudrait donc que je fasse également une boucle mais le problème c'est qu'il va me générer des grilles différentes pour chaque client alors que je voudrais qu'ils aient tous la même.
Avez-vous une idée pour résoudre dernier petit soucis?

En tout cas merci beaucoup pour la résolution de mon 1er problème.
0
cs_laurent1024 Messages postés 987 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 30 août 2012 25
4 mai 2006 à 12:33
Tu peux modifier la structure CLIENT. Tu remplace le tableau par un pointeur de tableau qui pointe sur un tableau unique. Ca risque de modifier le code mais la grille sera commun a tout tes clients sur le programme serveur
0
cs_lillie69 Messages postés 18 Date d'inscription lundi 27 mars 2006 Statut Membre Dernière intervention 6 mai 2006
4 mai 2006 à 14:10
Alors maintenant j'ai un segmentation fault depuis qu'on a généré une
grille aléatoirement puis on la recopie dans la grille des clients, on
a utilisé gdb qui nous dit que l'erreur se situe ici:
client[i].grille[j][k]=grille[j][k];

Voila le code modifié:



#include

#include



#include

#include

#include

#include

#include

#include

#include



#include "socket.h"

#include "transmission.h"

#include "bateau.h"





#define NJ 2 //nombre de joueurs







typedef struct

{

int com;

char nom_joueur[30];

int grille[10][10];



} CLIENT;











void * initialisation_joueur(void* voidparam)


{







CLIENT *client=(CLIENT*) voidparam;

char sms0[80]="Bienvenue ";

int i;




reception_chaine(client->com,client->nom_joueur,255);


int compte=strlen(client->nom_joueur);

for(i=10;inom_joueur[i-10];



transmettre_chaine(client->com,sms0);



pthread_exit(0);

return NULL;


}





void * envoi_grille(void* voidparam)


{

int i,j;

CLIENT *client=(CLIENT*) voidparam;

afficher_grille(client->grille);

for(i=0;igrille[i][j]);

}

pthread_exit(0);

return NULL;


}





int main()

{

CLIENT client[2*NJ];

pthread_t threads[2*NJ];

int connexion;

int port=12000;

int code;

int grille[10][10];

int i,j,k;

bateau *vaisseau[4];



/*for(i=0;i
0
cs_laurent1024 Messages postés 987 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 30 août 2012 25
4 mai 2006 à 14:50
Problème d'indice
tu fait for(k=0; k<10;
j++)
avec un k++ ca doit aller mieux
0
cs_lillie69 Messages postés 18 Date d'inscription lundi 27 mars 2006 Statut Membre Dernière intervention 6 mai 2006
4 mai 2006 à 14:54
okay,merci j'ai honte de pas mettre rendu compte de ctte erreur aussi bete.

Merci beaucoup
0
cs_laurent1024 Messages postés 987 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 30 août 2012 25
4 mai 2006 à 14:55
Le copier-coller n'est pas toujours l'amis des programmeurs :)
0
cs_lillie69 Messages postés 18 Date d'inscription lundi 27 mars 2006 Statut Membre Dernière intervention 6 mai 2006
4 mai 2006 à 15:13
Je suis désolée, mais j'ai encore quelques soucis

Je vais essayer d'expliquer clairement ce qu'il se passe: alors en fait
les bateaux sont donc bien posotionnés aléatoirement sur la grille qui
se trouve dans le serveur et celle ci s'affiche correctement.

Par contre chez le client il recoit à nouveau n'importe quoi sauf que
cette fois il recoit le même chiffre partout (-128754 quelque chose
comme ca)!

On dirait qu'il ne considère pas la bonne grille.

Je vous renvois mon code du client et du serveur:



CLIENT:

#include

#include

#include

#include

#include



#include "socket.h"

#include "transmission.h"

#include "bateau.h"







#define NJ 2 //nombre de joueurs





typedef struct

{

int com;

char nom_joueur[30];

int grille[10][10];



}JOUEUR;







void *lecture(void *voidparam)

{

JOUEUR *joueur=(JOUEUR*) voidparam;

char chaine[255];

int code;



code=reception_chaine(joueur->com, chaine, 255);

if(code com, chaine);

if(code grille);

pthread_exit(0);

return NULL;

}









int main()

{

JOUEUR *joueur;

int port=12000;

int grille[10][10];

initialiser_grille(grille);

Case * c;

c=(Case *)malloc(sizeof(Case) *1);



pthread_t threads[4];



printf("Quel est votre prenom? \n");



joueur->com= canal_communication("localhost", port);



if(joueur->com < 0)

return 1;







pthread_create(&threads[0], NULL, lecture, (void
*) &(joueur->com));

pthread_create(&threads[1], NULL, ecriture, (void *) &(joueur->com));





pthread_join(threads[0], NULL);

pthread_join(threads[1], NULL);



pthread_create(&threads[2], NULL, reception_grille, (void *) &(joueur));

pthread_join(threads[2], NULL);







close(joueur->com);



printf("stop\n");



return 0;

}







SERVEUR:

#include

#include



#include

#include

#include

#include

#include

#include

#include



#include "socket.h"

#include "transmission.h"

#include "bateau.h"





#define NJ 2 //nombre de joueurs







typedef struct

{

int com;

char nom_joueur[30];

int grille[10][10];



} CLIENT;











void * initialisation_joueur(void* voidparam)


{







CLIENT *client=(CLIENT*) voidparam;

char sms0[80]="Bienvenue ";

int i;




reception_chaine(client->com,client->nom_joueur,255);


int compte=strlen(client->nom_joueur);

for(i=10;inom_joueur[i-10];



transmettre_chaine(client->com,sms0);



pthread_exit(0);

return NULL;


}





void * envoi_grille(void* voidparam)


{

printf("bla");

int i,j;

CLIENT *client=(CLIENT*) voidparam;

afficher_grille(client->grille);

for(i=0;igrille[i][j]);

}

pthread_exit(0);

return NULL;


}





int main()

{

CLIENT * client[2*NJ];

pthread_t threads[2*NJ];

int connexion;

int port=12000;

int code;

int grille[10][10];

int i,j,k;

bateau *vaisseau[4];

for(i=0;i
0
cs_laurent1024 Messages postés 987 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 30 août 2012 25
4 mai 2006 à 15:28
Ca doit etre un problème dans le meme genre que précédement, sauf que la dans ton code, j'arrive meme pas a voir quand est que tu utilise les bateaux a part dans le main du serveur.
0
cs_lillie69 Messages postés 18 Date d'inscription lundi 27 mars 2006 Statut Membre Dernière intervention 6 mai 2006
4 mai 2006 à 15:32
Pour le moment on essaye juste de tranférer la grille c'est pour ca qu'on n'utilise pas encore les bateaux.

Mais ce que je ne comprends pas c'est pourquoi le serveur ne récupère
pas la grille qu'on lui a fait générer pour l'envoyer aux clients?

Aurait-on fait une erreur dans les passages de paramètres des threads?
0
cs_lillie69 Messages postés 18 Date d'inscription lundi 27 mars 2006 Statut Membre Dernière intervention 6 mai 2006
4 mai 2006 à 16:05
Nous avons testé et essayé de nouvelles choses et maintenant notre
serveur envoie correctement la grille alors que le client recoit
n'importe quoi, j'étais pourtant sur que ma fonction de réception
d'entier marche mais apparement l'erreur devrait venir que de la,enfin
je pense:



int transmettre_entier(int communication, int entier)

{



int code;

uint32_t nn;



// convertir l'entier au format reseau



nn= htonl(entier);



// transmettre l'entier

code= write(communication, &nn, sizeof(nn));

if(code < 0)

// erreur de transmission

return code;

return nn;

}







int reception_entier(int communication)

{

int n;

int code;

uint32_t nn;



// recevoir un entier au format reseau

code= read(communication, &nn, sizeof(nn));

if(code < sizeof(nn))

// reception incomplete

return -1;



// convertir en entier

n= ntohl(nn);

return n;

}



Apparement read ne marche pas car il nous renvoit -1 comme code si on
met un printf juste avant mais dans ce cas on devrait avoir que des -1
alors que ce n'est pas le cas.

Ou est le problème svp?

Merci
0
Rejoignez-nous