Forum Programmation.c Obtenir le numero d'un port réseau libre

Posté par  .
Étiquettes : aucune
0
28
sept.
2007
Bonjour,

Je suis entrain de réaliser un système de communication inter processus. En simplifiant l'architecture on obtient cela:

un processus maitre avec un numero de port connu de tout le monde
et des processus esclave possédant un UID unique et un numero de port

la première chose que fait un processus esclave est de communiquer son UID et son port au processus maitre.

Mes processus esclaves peuvent donc utiliser n'importe quel port ouvert.
Pour obtenir un port disponible j'utilsie la méthode suivante (cardique s'abstenir)

j'essaye d'ouvrir le port du processus maitre + 1 si la focntion ne retourne une erreur je tente avec +2 etc ... jusqu'a trouvé un port dispo.

Ce code est nul pour plein de raisons (performance, boucle potentiellement infinie, etc etc etc)

Je cherche un appel système me permettant de demander au kernel un port dispo.

Est ce que quelqu'un sait le faire en O(1) ??

D'avance merci
Cordialement
  • # bind

    Posté par  . Évalué à 3.

    Tu utilises bind en spécifiant le port 0, et ça va automatiquement utiliser le premier port dispo.
  • # bind(0)

    Posté par  . Évalué à 3.

    Au lieu de transmettre à bind() ton port testé en boucle via my_addr.sin_port = htons(port++), il te suffit de mettre sin_port à 0 : bind() t'allouera automatiquement un port libre.

    Pour récupérer le port ainsi alloué à ta socket "sockfd" , utilise getsockname:

    struct sockaddr_in name;
    int namelen;

    namelen = sizeof(name);
    err = getsockname(sockfd, &name, &namelen);
    printf(" err = %d, port alloué = %d\n", err, ntohs(name.sin_port));



    Cependant, sache que tu n'as pas besoin de communiquer explicitement ton port via un protocole à toi au maître : du moment que tu fais une connexion à sa socket (via un connect() ou un sendto()), le maitre récupère automatiquement l'identifiant (IP, port) de l'appelant (man getpeername). Tu peux donc te contenter de fournir juste l'UID.
    • [^] # Re: bind(0)

      Posté par  . Évalué à 2.

      Ma remarque finale n'est peut-être pas adaptée selon la façon dont tu architectures tes maître/esclaves. Est-ce que c'est les esclaves qui se connectent une fois pour toute au maître, ou bien ils envoient un message initial (via une socket quelconque) et le maitre les recontacte plus tard sur leur socket ouverte par le bind(0) ?
      Dans le 1er cas, tu n'as pas besoin du tout de faire un bind, juste un socket() puis un connect() vers le maitre. Dans le 2eme cas, continue comme tu l'expliques, mais c'est bizarrement foutu.

      Je te conseille de lire "Beej's Guide to Network Programming" http://www.beej.us/guide/bgnet/ qui illustre de façon très claire les bases d'un client/serveur.
      • [^] # Re: bind(0)

        Posté par  . Évalué à 2.

        Super Merci beaucoup
        • [^] # Re: bind(0)

          Posté par  . Évalué à 2.

          J'ajouterais que si c'est uniquement pour faire de l'IPC, alors il ne faut pas utiliser spécialement le réseau pour faire cela !

          Vois plutôt du coté des IPC SysV (mémoire partagée, sémaphore et file de messages), et utilise plutôt les sockets Unix ...
  • # et dbus ?

    Posté par  . Évalué à 1.

    J'ai peur de dire une connerie, mais est-ce que dbus n'est pas fait exactement pour cela ?

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.