Erreur de Segmentation sur les sockets [Résolu]

Signaler
Messages postés
108
Date d'inscription
samedi 31 mars 2012
Statut
Membre
Dernière intervention
16 juin 2013
-
Messages postés
108
Date d'inscription
samedi 31 mars 2012
Statut
Membre
Dernière intervention
16 juin 2013
-
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

Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
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].
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
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));
}


@++
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
apres verif, ca semble bon.
Ton allocation de tableau ne va pas
int ** mat = malloc(3 * sizeof(int*
);
Messages postés
108
Date d'inscription
samedi 31 mars 2012
Statut
Membre
Dernière intervention
16 juin 2013

ok je vais voir je le met au niveau du serveur ou du client
Messages postés
108
Date d'inscription
samedi 31 mars 2012
Statut
Membre
Dernière intervention
16 juin 2013

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
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
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.

@++
Messages postés
108
Date d'inscription
samedi 31 mars 2012
Statut
Membre
Dernière intervention
16 juin 2013

je veut bien je suis vraiment bloqué:
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
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 ?

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

@++
Messages postés
108
Date d'inscription
samedi 31 mars 2012
Statut
Membre
Dernière intervention
16 juin 2013

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
Messages postés
108
Date d'inscription
samedi 31 mars 2012
Statut
Membre
Dernière intervention
16 juin 2013

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..
Messages postés
108
Date d'inscription
samedi 31 mars 2012
Statut
Membre
Dernière intervention
16 juin 2013

T'as raison si j'envoie mat[i][i] j'ai pas l'erreur merci
Messages postés
1466
Date d'inscription
vendredi 2 janvier 2004
Statut
Modérateur
Dernière intervention
14 février 2014
1
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, ...

@++
Messages postés
108
Date d'inscription
samedi 31 mars 2012
Statut
Membre
Dernière intervention
16 juin 2013

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