Erreur de Segmentation sur les sockets [Résolu]

andoid 108 Messages postés samedi 31 mars 2012Date d'inscription 16 juin 2013 Dernière intervention - 29 févr. 2012 à 14:54 - Dernière réponse : andoid 108 Messages postés samedi 31 mars 2012Date d'inscription 16 juin 2013 Dernière intervention
- 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;
}
Afficher la suite 

Votre réponse

14 réponses

Meilleure réponse
cs_patatalo 1466 Messages postés vendredi 2 janvier 2004Date d'inscription 14 février 2014 Dernière intervention - 29 févr. 2012 à 21:33
3
Merci
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].

Merci cs_patatalo 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 72 internautes ce mois-ci

Commenter la réponse de cs_patatalo
cs_patatalo 1466 Messages postés vendredi 2 janvier 2004Date d'inscription 14 février 2014 Dernière intervention - 29 févr. 2012 à 20:42
0
Merci
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));
}


@++
Commenter la réponse de cs_patatalo
cs_patatalo 1466 Messages postés vendredi 2 janvier 2004Date d'inscription 14 février 2014 Dernière intervention - 29 févr. 2012 à 20:47
0
Merci
apres verif, ca semble bon.
Ton allocation de tableau ne va pas
int ** mat = malloc(3 * sizeof(int*
);
Commenter la réponse de cs_patatalo
andoid 108 Messages postés samedi 31 mars 2012Date d'inscription 16 juin 2013 Dernière intervention - 29 févr. 2012 à 20:51
0
Merci
ok je vais voir je le met au niveau du serveur ou du client
Commenter la réponse de andoid
andoid 108 Messages postés samedi 31 mars 2012Date d'inscription 16 juin 2013 Dernière intervention - 29 févr. 2012 à 20:58
0
Merci
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
Commenter la réponse de andoid
cs_patatalo 1466 Messages postés vendredi 2 janvier 2004Date d'inscription 14 février 2014 Dernière intervention - 29 févr. 2012 à 21:06
0
Merci
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.

@++
Commenter la réponse de cs_patatalo
andoid 108 Messages postés samedi 31 mars 2012Date d'inscription 16 juin 2013 Dernière intervention - 29 févr. 2012 à 21:09
0
Merci
je veut bien je suis vraiment bloqué:
Commenter la réponse de andoid
cs_patatalo 1466 Messages postés vendredi 2 janvier 2004Date d'inscription 14 février 2014 Dernière intervention - 29 févr. 2012 à 21:16
0
Merci
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 ?

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

@++
Commenter la réponse de cs_patatalo
andoid 108 Messages postés samedi 31 mars 2012Date d'inscription 16 juin 2013 Dernière intervention - 29 févr. 2012 à 21:26
0
Merci
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
Commenter la réponse de andoid
andoid 108 Messages postés samedi 31 mars 2012Date d'inscription 16 juin 2013 Dernière intervention - 29 févr. 2012 à 21:42
0
Merci
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..
Commenter la réponse de andoid
andoid 108 Messages postés samedi 31 mars 2012Date d'inscription 16 juin 2013 Dernière intervention - 29 févr. 2012 à 22:43
0
Merci
T'as raison si j'envoie mat[i][i] j'ai pas l'erreur merci
Commenter la réponse de andoid
cs_patatalo 1466 Messages postés vendredi 2 janvier 2004Date d'inscription 14 février 2014 Dernière intervention - 2 mars 2012 à 08:08
0
Merci
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, ...

@++
Commenter la réponse de cs_patatalo
andoid 108 Messages postés samedi 31 mars 2012Date d'inscription 16 juin 2013 Dernière intervention - 2 mars 2012 à 08:19
0
Merci
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
Commenter la réponse de andoid

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.