2009-09-02 6 views
110

J'essaie de jouer avec la communication inter-processus et puisque je ne pouvais pas comprendre comment utiliser les canaux nommés sous Windows, je pensais utiliser des sockets réseau. Tout se passe localement. Le serveur est capable de lancer des esclaves dans un processus séparé et écoute sur un port. Les esclaves font leur travail et soumettent le résultat au maître. Comment puis-je savoir quel port est disponible? Je suppose que je ne peux pas écouter sur le port 80 ou 21? J'utilise Python, si cela diminue les choix.Sur localhost, comment puis-je choisir un numéro de port gratuit?

Merci!

+1

Soit dit en passant, si vous choisissez juste un numéro de port aléatoire ou ish aléatoire (de préférence supérieur à 1024), il sera probablement disponible . Vous pouvez même utiliser le port 80 ou 21 ou autre, tant qu'aucun autre programme ne l'écoute. À un moment donné, sur un système normal, seule une petite fraction des ports est utilisée. –

+17

Choisir un port aléatoire n'est pas une bonne idée - laissez le système d'exploitation en choisir un pour vous. – Corehpf

+0

Sur POSIX: http://stackoverflow.com/questions/913501/how-to-let-kernel-choose-a-port-number-in-the-range-1024-5000-in-tcp-socket-pr –

Répondre

170

Ne pas lier à un port spécifique ou ne pas lier au port 0, par ex. sock.bind(('', 0)). Le système d'exploitation choisira alors un port disponible pour vous. Vous pouvez obtenir le port qui a été choisi en utilisant sock.getsockname()[1], et le transmettre aux esclaves afin qu'ils puissent se reconnecter.

+2

Voir http://stackoverflow.com/a/2838309/3538289 pour un exemple de 'sock.bind (('', 0))' – cevaris

+4

Comment transmettez-vous le numéro aux esclaves? On dirait un problème de poule et d'oeuf pour moi. – Sebastian

+0

Si les esclaves sont créés après la liaison, vous pouvez simplement les passer en paramètre lors de leur création. Vous pouvez également l'écrire dans une mémoire partagée ou un fichier auquel les deux peuvent accéder, ou un serveur central accessible via un numéro de port bien connu peut en assurer le suivi. – mark4o

35

Lier le socket au port 0. Un port libre aléatoire de 1024 à 65535 sera sélectionné. Vous pouvez récupérer le port sélectionné avec getsockname() juste après bind().

2

Vous pouvez écouter sur le port que vous voulez; en général, les applications utilisateur doivent écouter les ports 1024 et supérieurs (jusqu'à 65535). La principale chose si vous avez un nombre variable d'auditeurs est d'allouer une gamme à votre application - disons 20000-21000, et EXCEPTIONS CATCH. C'est ainsi que vous saurez si un port est inutilisable (utilisé par un autre processus, en d'autres termes) sur votre ordinateur.

Toutefois, dans votre cas, vous ne devriez pas avoir de problème à utiliser un seul port codé en dur pour votre écouteur, à condition d'imprimer un message d'erreur si la liaison échoue. Notez également que la plupart de vos sockets (pour les esclaves) n'ont pas besoin d'être explicitement liés à des numéros de port spécifiques - seules les sockets qui attendent les connexions entrantes (comme votre maître ici) devront être écoutées et reliées à un port. Si un port n'est pas spécifié pour une socket avant son utilisation, le système d'exploitation attribuera un port utilisable à la socket. Lorsque le maître souhaite répondre à un esclave qui lui envoie des données, l'adresse de l'expéditeur est accessible lorsque l'auditeur reçoit des données.

Je présume que vous utiliserez UDP pour cela?

6

Par souci de bout de ce que les gars ont expliqué ci-dessus:

import socket 
from contextlib import closing 

def find_free_port(): 
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: 
     s.bind(('', 0)) 
     return s.getsockname()[1] 
+0

si sur localhost: peut-être 's.bind (('localhost', 0))' est mieux – codeskyblue

Questions connexes