12
votes

Obtenez un port aléatoire pour la prise UDP

J'ai besoin de créer un programme qui communiquera avec d'autres programmes sur le même ordinateur via des sockets UDP. Il va lire les commandes de STDIN et certaines de ces commandes pourront envoyer / recevoir des paquets sans mettre d'entre eux l'exécution. J'ai lu des informations là-bas, mais comme je ne connais pas la programmation de la prise et que je dois l'obtenir rapidement, j'ai les questions suivantes:

  1. Je dois obtenir un port inutilisé aléatoire pour le programme d'écouter et de réserver pour que d'autres programmes puissent communiquer avec cela et que le port n'est pas réservé par un autre programme. J'ai aussi besoin de stocker le numéro de port sur une variable pour une utilisation future.
  2. Depuis que la communication est entre les processus sur la même machine, je me demande si je peux utiliser pf_local.

    Un échantillon de code de la configuration de cette prise serait bienvenu, ainsi qu'un exemple d'envoi / de réception de chaînes de caractères.


2 commentaires

OS Linux utilisant des bibliothèques standard


Pourquoi communiquer entre les processus à l'aide d'une prise? Est-ce juste pour le plaisir de le faire? ;)


3 Réponses :


22
votes

appel BIND () Spécifier le port 0. Cela permettra au système d'exploitation de choisir un port inutilisé. Vous pouvez ensuite utiliser getockname () pour revenir au port choisi.


4 commentaires

C'est un bon moyen de le faire, mais cela ne serait certainement pas une manière aléatoire de le faire.


Je suppose que si vous vouliez un port vraiment aléatoire, vous pouvez continuer à essayer de se lier à ((rand ()% 65535) +1) jusqu'à la liaison retour du succès.


Il sera aléatoire dans le fait que vous ne saurez pas quel port est choisi jusqu'à ce que la contraignante réussisse. La liaison au port 0 permet au système d'exploitation de choisir le premier port inutilisé disponible. Si BIND () réussit, vous êtes garané pour avoir un port qui n'est utilisé que par vous et personne d'autre. Vos exigences énoncées ne nécessitent pas que cela soit vraiment aléatoire de persaïque, juste unique, et ce sera.


Je pense que le port est retourné par BIND (.., 0) n'est pas si bon pour une utilisation persistante; Voir ma réponse pour les détails.



0
votes

S'il s'agit d'un port aléatoire est en fait important, vous devez faire quelque chose comme: xxx

Spécifiez ce port dans la liaison. Si elle échoue, choisissez une nouvelle (pas besoin de regrener le générateur aléatoire. Si le port aléatoire n'est pas important, regardez la réponse de Rémy Lebeau.


2 commentaires

Vous devriez garder une trace de quels ports que vous avez tentés, vous n'essayez pas de ne plus essayer de les lier puisqu'ils ont échoué la première fois.


True, bien que la probabilité que vous répétiez des ports dans la séquence pseudo-aléatoire avant de trouver un port ouvert est assez faible.



1
votes

Réponse de Remy Lebeau est bon si vous avez besoin d'un port temporaire. Ce n'est pas si bon que vous avez besoin d'un port réservé persistant car d'autres logiciels utilisent également la même méthode pour obtenir un port (y compris la pile TCP OS qui nécessite un nouveau port temporaire pour chaque connexion).

alors ce qui suit pourrait arriver:

  1. Vous appelez BIND avec 0 et getockName () pour obtenir un port;
  2. Enregistrez-le ensuite dans Config (ou dans plusieurs configurations) pour des utilisations futures;
  3. logiciel qui nécessite ce port démarre et lie le port.

    Ensuite, vous devez par exemple. Redémarrez le logiciel:

    1. Software s'arrête et abîne le port: le port peut maintenant être renvoyé par BIND (0) et obtient à nouveau ();
    2. E.g. TCP Stack a besoin d'un port et lie votre port;
    3. Le logiciel ne peut pas démarrer car le port est déjà lié.

      Donc, pour "Usages futurs", vous avez besoin d'un port qui n'est pas dans la plage de ports éphémères (c'est-à-dire la plage de laquelle la liaison (hôte, 0) renvoie un port).

      Ma solution pour ce numéro est le utilitaire de ligne de commande de port-pour .


2 commentaires

Très rarement, si jamais, aurez-vous besoin de récupérer un port éphémère la première fois et de le sauvegarder pour la réutilisation des connexions ultérieures. J'ai écrit un code de douille depuis plus de 10 ans et je n'ai jamais eu besoin de le faire, pas une fois. En règle générale, vous utilisez soit des ports éphémères à chaque fois (et pour les serveurs, fournir un moyen de découvrir que le port de manière dynamique), ou si vous avez l'utilisateur de spécifier un port fixe dans la configuration de votre application, auquel cas l'utilisateur garantit que le port est toujours disponible pour utilisation.


Si ma compréhension de la question est correcte (en particulier "1" partie), elle le demande. Cela peut ne pas être le cas cependant. Le boîtier d'utilisation ne doit pas faire de l'utilisateur Assurez-vous que le port est toujours disponible mais pour créer un logiciel garantissant que le port est disponible.