Socket fonction Bind génère segmentation fault

Résolu
Bonjour,

Je suis en train de faire un petit serveur en C sous Linux et il s'avère que lorsque j'utilise ma fonction bind, le code génère une segmentation fault.

voici le code en cause :

int setServer(int *sockNumber){
    struct sockaddr_in sockAddr;

    //Création du socket
    if((*sockNumber=socket(AF_INET, SOCK_STREAM, 0))==-1){
        writeLog(FILENAME, "Erreur Socket Serveur");
        return -1;
    }


    //Bind du socket
    sockAddr.sin_family=AF_INET;
    sockAddr.sin_port=htons(50000);
    sockAddr.sin_addr.s_addr=inet_addr("107.0.0.1");


    if (bind (*sockNumber, (struct sockaddr *)&sockAddr, sizeof(sockAddr))==-1)
    {
        perror(errno);
        writeLog(FILENAME, "Erreur Bind");
        return -1;
    }
    else printf("wp");
    return 1;
}


Je suis un petit peu à la bourre et je n'arrive pas à comprendre d'où vient l'erreur. Et sans ça, je ne sais pas avancer.

Merci beaucoup pour votre éventuelle réponse

3 réponses

  1. j'ai aussi un petit doute sur ta structure, essaye de rajouter :

      memset(&sockAddr, 0, sizeof(struct sockaddr_un));


    histoire d'initialiser ta structure (sous la ligne //Bind du socket).
    0
    1. Je sais pas si tu as vu le message que j'ai laissé au dessus ?
      Voilà, ça fonctionne alors que je ne pense pas avoir changé quelque chose au code :

      int setServer(int *sockNumber){
          struct sockaddr_in sockAddr;
          char phrase[500];
          //Création du socket
          if((*sockNumber=socket(AF_INET, SOCK_STREAM, 0))==-1){
              writeLog(FILENAME, "Erreur Socket Serveur");
              return -1;
          }
      
          //Bind du socket
          sockAddr.sin_family=AF_INET;
          sockAddr.sin_port=htons(50000);
          sockAddr.sin_addr.s_addr =inet_addr("127.0.0.1");
      
      
          if (bind (*sockNumber, (struct sockaddr *)&sockAddr, sizeof(sockAddr))==-1)
          {
              writeLog(FILENAME, "Erreur Bind");
              return -1;
          }
          return 1;
      }
      
      0
    2. oui j'avais vu ^^. et si ce n'est la déclaration d'un char* en plus, pas de différence x)

      Après vu qu'on a pas un visu de tout il est difficile de dire le pourquoi du comment ... mais après un segmentation fault vient d'un fait qu'espace non alloué est utilisé (ou en tout cas qu'on tente de), donc tu n'es pas à l'abris de revoir l'erreur apparaître je pense.

      Bien que je ne sois pas certain de la nécessitée ( je peux pas tester =/ ), rajouter le memset serai je pense une petite sécuritée en plus (en pensant à le libérer à la fin =p) qui t'évitera peu être de ravoir le problème.

      Tiens moi au courant en tout cas, ca m'interesse ^^
      0
    3. Contributeur
      par rapport à ton premier message, tu as modifié l'adresse IP du bind. 127.0.0.1 est le localhost, 107.0.0.1, je ne connais pas. L'erreur viens peut être de là : bind ne triouvant pas l'adresse en local plante. -> à tester pour en être certain.
      0
    4. Oh oui ! Bien vu ça ! Effectivement, je viens de changer en "107.0.0.1" et bind génère une erreur...

      Quelle erreur stupide quand même...

      Merci beaucoup !
      0
    5. Contributeur
      Ce n'est pas stupide comme erreur, elle peut intervenir de façon justifié dans d'autres cas. Ce que je trouve stupide c'est que bind plante tout sans laisser de message clair.
      0
  2. Contributeur
    Salut, je pense que l'erreur peut venir du sizeof. Tu lui donnes sockAddr qui a la taille du type "sockaddr_in". Dans mes programme réseau, je passe "sizeof(sockaddr)" en troisième argument de bind.
    Si ce n'est pas ça, peut être le numéro du port qui est trop élevé ou déjà occupé ou réservé ?
    0
    1. Je vais tenter le coup, mais je cast quand même ma variable de type "sockaddr_in" en "sockaddr".

      Je doute qu'il faille changer mon sizeof. Je vous tiens au courant.
      0
    2. C'est à ne plus rien comprendre. J'ai réécrit entièrement ma fonction et en fait, j'ai écrit exactement la même chose... Cela fonctionne...

      Je n'ai vraiment aucune idée du pourquoi cette erreur apparaissait avant et plus maintenant.
      0
  3. salut,
    j'ai juste une petite question concernant tes variables :
    en entrée tu donne un pointeur (int *) et tu redonne la valeur avec l'* , et donc tu passe le paramètre ** ... sachant que les methodes bind et socket (par sûr pour lui mais ca doit être ca) demandent l'adresse de ton int, les valeurs deviennent fausses ...

    essaye plutot d'appeler tes fonctions de cette manière :
    PAS :
    *sockNumber=socket(... 

    MAIS :
    sockNumber=socket(... 


    PAS :
    bind (*sockNumber, (struct sockaddr *)&sockAddr,...

    MAIS :
    bind (sockNumber,sockAddr,... 


    j'ai un peu l'impression que la question des pointeurs reste un confus ...

    dis moi ce que ca donnera

    naga
    0
    1. Contributeur
      non, tu as tors, il fait comme il faut.
      0
    2. Voilà, je passe en argument un pointeur sur un entier et le premier paramètre de la fonction bind est le numéro de la socket utilisée (une valeur entière). Il faut donc que j'envoie à la fonction *sockNumber.
      0
    3. @char snipeur : ah oui en effet, va falloir que je révise mon adressage >_< (ca me perturbe de voir du *p=a et non p=&a ... )
      0
    4. mais d'ailleurs non, j'ai eu un doute mais il y a bien un soucis avec les pointeurs, dire

       
      int * var;
      *var = a(); 

      donne un ** Oo

      exemple : on déclare en entrée :
      int *sockNumber


      et quand on le passe en paramètre dans bind, on lui donne :

      bind (*sockNumber,(struct sockaddr *)&sockAddr 


      donc **socknumber ... (d'ailleur par la même occasion caster l'adresse de sockAddr en adresse sockaddr est pas utile je pense ...)

      bind étant :
      int bind(int sockfd, const struct sockaddr *addr,
               socklen_t addrlen);


      mieux vaut lui passer &sockNumber non ? (je me remet dans le bain par la meme occasion ^^)
      0
    5. Contributeur
      Je prends le problème en cours :-)
      int *sockNumber
      et quand on le passe en paramètre dans bind, on lui donne :
      bind (*sockNumber,(struct sockaddr *)&sockAddr
      donc **socknumber .

      Bah non. sockNumber est un pointeur sur un entier. *sockNumber est donc l'entier pointé. Il s'agit bien d'un int. Et non d'un int**.

      mieux vaut lui passer &sockNumber non ?
      Surtout pas. Car là pour le coup tu auras un int **.
      0