Erreur de Segmentation sur les sockets

Résolu
andoid Messages postés 108 Date d'inscription samedi 31 mars 2012 Statut Membre Dernière intervention 16 juin 2013 - 29 févr. 2012 à 14:54
andoid Messages postés 108 Date d'inscription samedi 31 mars 2012 Statut Membre Dernière intervention 16 juin 2013 - 2 mars 2012 à 08:19
Bonjour
Je blogue sur mon code depuis 2h j'ai une erreur de segmentation à la reception du coté client au faite j'envoie un tableau 2d (d=dimension)
lorque je veux l'afficher j'ai une erreur de segmentation et je galére pour la trouver.
////////////////////// Programme Serveur


#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include
#include
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(s) close(s)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PORT 23
#define TAILLE 100
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;


//////////////////////////////////////



int** initGrille()
{

int i,j;
int ** mat = malloc(3 * sizeof(int));
for( i = 0; i < 3; ++i)
{
mat[i] = malloc(3 *sizeof(int));
}

for (i=0;i<3;i++)
{
for (j=0;j<3;j++)
{
mat[i][j]=0;

}

}

return mat;

}



////////////////////////////////////////


int main(void)
{

int erreur = 0,i,j;

char buf[TAILLE]= "Bonjour !";;
int **mat;
mat= initGrille();
mat[0][0]=1;

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

for(j=0;j<3;j++)
{

printf("%i \t",mat[i][j]);

}

printf("\n");

}

/* Socket et contexte d'adressage du serveur */
SOCKADDR_IN sin;
SOCKET sock;
socklen_t recsize = sizeof(sin);

/* Socket et contexte d'adressage du client */
SOCKADDR_IN csin;
SOCKET csock;
socklen_t crecsize = sizeof(csin);

int sock_err;


if(!erreur)
{
/* Création d'une socket */
sock = socket(AF_INET, SOCK_STREAM, 0);

/* Si la socket est valide */
if(sock != INVALID_SOCKET)
{
printf("La socket %d est maintenant ouverte en mode TCP/IP\n", sock);

/* Configuration */
sin.sin_addr.s_addr = htonl(INADDR_ANY); /* Adresse IP automatique */
sin.sin_family = AF_INET; /* Protocole familial (IP) */
sin.sin_port = htons(PORT); /* Listage du port passage au format réseau */
sock_err = bind(sock, (SOCKADDR*)&sin, recsize);

/* Si la socket fonctionne */
if(sock_err != SOCKET_ERROR)
{
/* Démarrage du listage (mode server) */
sock_err = listen(sock, 5);
printf("Listage du port %d...\n", PORT);

/* Si la socket fonctionne */
if(sock_err != SOCKET_ERROR)
{
/*Pour que le pére detruit à lui seul les processus zombie on place ce code avant la boucle fausse signal(SIGCHLD,SIG_IGN)*/
/*Pour un serveur parallel c'est là que je vais mettre ma boucle while(1) */
/* Attente pendant laquelle le client se connecte */
printf("Patientez pendant que le client se connecte sur le port %d...\n", PORT);
csock = accept(sock, (SOCKADDR*)&csin, &crecsize);
/*Aprés le teste sur la socket csock je peux faire un fork() pour que le fils s'occupe du traitement des demandes de service des clients */
printf("Un client se connecte avec la socket %d de %s:%d\n", csock, inet_ntoa(csin.sin_addr), htons(csin.sin_port));
sock_err=send(csock,&mat,sizeof(mat),0);

if(sock_err!=SOCKET_ERROR)
{
printf("Message envoyé\n");
shutdown(csock,1);

}
else
perror("send");
}

else
perror("listen");
}
else
perror("bind");

/* Fermeture de la socket client et de la socket serveur */
printf("Fermeture de la socket client\n");
closesocket(csock);
printf("Fermeture de la socket serveur\n");
closesocket(sock);
printf("Fermeture du serveur terminée\n");
}
else
perror("socket");


}

return EXIT_SUCCESS;
}
////////////////////////////////////////// Client


#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include
#include
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(s) close(s)
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;


#include <stdio.h>
#include<string.h>
#include <stdlib.h>
#define PORT 23
#define TAILLE 100


////////////////////////////////////





//////////////////////////////////////



int** initGrille()
{

int i,j;
int ** mat = malloc(3 * sizeof(int));
for( i = 0; i < 3; ++i)
{
mat[i] = malloc(3 *sizeof(int));
}

for (i=0;i<3;i++)
{
for (j=0;j<3;j++)
{
mat[i][j]=0;

}

}

return mat;

}





//////////////////////////////////





int main(void)
{

int erreur = 0;


SOCKET sock;
SOCKADDR_IN sin;
char buffer[TAILLE]="";

int **mat;
mat=initGrille();

if(!erreur)
{
/* Création de la socket */
sock = socket(AF_INET, SOCK_STREAM, 0);

/* Configuration de la connexion */
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);

/* Si l'on a réussi à se connecter */
if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
{
printf("Connection à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));

/* Si l'on reçoit des informations : on les affiche à l'écran */
if(recv(sock, &mat, sizeof(mat), 0) != SOCKET_ERROR)
printf("Recu : %i\n",mat[0][0]);
shutdown(sock,2);
}
/* sinon, on affiche "Impossible de se connecter" */
else
{
printf("Impossible de se connecter\n");
}

/* On ferme la socket */
closesocket(sock);


}

/* On attend que l'utilisateur tape sur une touche, puis on ferme */
getchar();

return EXIT_SUCCESS;
}

14 réponses

cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 1
29 févr. 2012 à 21:33
le probleme est que tu es obligé d'allouer dans un ordinateur l'espace necessaire aux données que tu vas envoyer/recevoir. Les adresses ou le tableau sera stocké est différent d'un ordi à l'autre, l'envoi/reception de ces adresses est inutile.

Tu dois envoyer/recevoir les valeurs mat[i][j].
3
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 1
29 févr. 2012 à 20:42
salut,

ceci est faux. A cause de la post incrémentation, la valeur 2 ne sera pas initialisée:

for( i = 0; i < 3; ++i)
{
mat[i] = malloc(3 *sizeof(int));
}


@++
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 1
29 févr. 2012 à 20:47
apres verif, ca semble bon.
Ton allocation de tableau ne va pas
int ** mat = malloc(3 * sizeof(int*
);
0
andoid Messages postés 108 Date d'inscription samedi 31 mars 2012 Statut Membre Dernière intervention 16 juin 2013
29 févr. 2012 à 20:51
ok je vais voir je le met au niveau du serveur ou du client
0

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

Posez votre question
andoid Messages postés 108 Date d'inscription samedi 31 mars 2012 Statut Membre Dernière intervention 16 juin 2013
29 févr. 2012 à 20:58
Toujours le même probléme j'ai en effet modifié le client avec le code que tu m'as passé
et rien toujours le même probléme
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 1
29 févr. 2012 à 21:06
re,

Il se peux effectivement que int et int* aient la même taille mais le code est plus correct comme indiqué et on sait jamais.

L'erreur doit être ici:
if(recv(sock, &mat, sizeof(mat), 0) != SOCKET_ERROR)

Je verifie.

@++
0
andoid Messages postés 108 Date d'inscription samedi 31 mars 2012 Statut Membre Dernière intervention 16 juin 2013
29 févr. 2012 à 21:09
je veut bien je suis vraiment bloqué:
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 1
29 févr. 2012 à 21:16
Tu peux regarder:

&mat est l'adresse d'un pointeur de pointeur de int.
taille = 4 octets (32bits)

combien de données reçois tu ?

@++
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 1
29 févr. 2012 à 21:23
Attends, tu alloues ton tableau mais tu écrases l'adresse de l'allocation par ce que tu recois.

@++
0
andoid Messages postés 108 Date d'inscription samedi 31 mars 2012 Statut Membre Dernière intervention 16 juin 2013
29 févr. 2012 à 21:26
Oui au faite l'idée est d'allouer le tableau pour pouvoir recevoir un tableau je sais pas si elle est bonne.
Par contre j'ai tester l'inverse recevoir puis allouer mais rien
0
andoid Messages postés 108 Date d'inscription samedi 31 mars 2012 Statut Membre Dernière intervention 16 juin 2013
29 févr. 2012 à 21:42
Ah ok mais ya pas moyen d'envoyer le tableau entier alors...
Parce que le but est de gérer une grille ou ce deplaceront des joueurs je me suis dit voila un tableau est bien pour gérer cela.
Lorsque le client se connecte faut qu'il me donne la position de ses joueurs et cela marche bien.
Une fois le placement fait le serveur doit envoyer la grille au client pour qu'une voir la position des ennemis.
Si je dois envoyer case par case ca va être lourd..
0
andoid Messages postés 108 Date d'inscription samedi 31 mars 2012 Statut Membre Dernière intervention 16 juin 2013
29 févr. 2012 à 22:43
T'as raison si j'envoie mat[i][i] j'ai pas l'erreur merci
0
cs_patatalo Messages postés 1466 Date d'inscription vendredi 2 janvier 2004 Statut Modérateur Dernière intervention 14 février 2014 1
2 mars 2012 à 08:08
re,

C'est la seule solution mais il doit être possible de limiter le volume d'echanges de données en retravaillant l'algorithme, par exemple, différencier les données reçues par une variable puis, envoyer seulement les mouvements, ...

@++
0
andoid Messages postés 108 Date d'inscription samedi 31 mars 2012 Statut Membre Dernière intervention 16 juin 2013
2 mars 2012 à 08:19
J'ai réussi à le faire merci par contre au niveau de mon serveur si un client A se connecte et place ces joueurs dans la grille puis un client B j'arrive pas à lui envoyer la même grille deja modifie par A. En effet le serveur lui envoie une nouvelle grille je me dis qu'il l'est traite différemment alors que la partie se joue entre deux clients
0