2010-01-25 5 views
8

Ich habe ein Python-Programm mit vielen Threads. Ich dachte daran, einen Socket zu erstellen, ihn an localhost zu binden und die Threads an diesem zentralen Ort lesen/schreiben zu lassen. Ich möchte jedoch nicht, dass dieser Socket für den Rest des Netzwerks offen ist, nur Verbindungen von 127.0.0.1 sollten akzeptiert werden. Wie würde ich das (in Python) machen? Und ist das ein passendes Design? Oder gibt es etwas Eleganteres?Erstellen eines Sockets nur für lokale Host-Verbindungen

Antwort

0

Wenn Sie sock.bind ((Port, '127.0.0.1')) ausführen, wird nur auf localhost und nicht auf anderen Schnittstellen gehorcht, das ist alles was Sie brauchen.

6

Bei einer Buchse mit socket.socket() erstellt haben, können Sie bind() vor Hören verwenden:

socket.bind(('127.0.0.1', 80)) 

Verwendung der Adresse 127.0.0.1 zeigt an, dass die Buchse nur an die lokale Schnittstelle binden sollte.

+0

Verbindet das nicht mit "INADDR_ANY"? –

+0

Nicht gemäß http://www.amk.ca/python/howto/sockets/ obwohl die tatsächliche Python-Dokumentation besagt, dass '''' äquivalent zu 'INADDR_ANY' ist. Ich werde meine Antwort aktualisieren. –

+1

Es bindet an INADDR_ANY, wenn Sie es sagen (indem Sie einen Host von '' angeben). Das Angeben eines Hosts von '127.0.0.1' bindet ihn an 127.0.0.1 – nos

5

http://www.amk.ca/python/howto/sockets/

Zeigt einige Buchse Beispiel. Dieser Leckerbissen ist interessant für Sie Ich denke

wir verwendeten socket.gethostname(), so dass der Sockel für die Außenwelt sichtbar wäre. Wenn wir s.bind (('', 80)) oder s.bind (('localhost', 80)) oder s.bind (('127.0.0.1', 80)) benutzt hätten, hätten wir immer noch einen "Server" "Buchse, aber eine, die nur innerhalb der gleichen Maschine sichtbar war.

Ich denke, es ist Ihre Antwort (siehe unten Korrektur)

In Bezug auf die Gültigkeit für Thread-Kommunikation der Verwendung dieser Methode. Ich bin mir nicht sicher, wie gut diese mehrere Threads und Lesen Griffe/Schreiben

EDIT

Es scheint ein Python-Rezept unten, dass hat einige inter-thread Kommunikation

http://code.activestate.com/recipes/491281/

haben verknüpft zu sein Spaß!

EDIT

Der Artikel ist falsch und wie erwähnt "s.bind (('', 80)) binden an INADDR_ANY"

+1

Dieser Artikel ist falsch. s.bind (('', 80)) wird an INADDR_ANY gebunden. – JimB

+0

Danke dafür, dass ich bearbeiten werde, um zu widerspiegeln – petantik

2

Sie könnten die queue module von der Norm verwenden möchten, Bibliothek stattdessen. Es wurde speziell entwickelt, um die Kommunikation zwischen Threads zu erleichtern. Ein Angebot aus der Dokumentation:

Das Queue-Modul implementiert Multi-Producer- und Multi-Consumer-Warteschlangen. Es ist besonders nützlich in der Thread-Programmierung, wenn Informationen sicher zwischen mehreren Threads ausgetauscht werden müssen. Die Queue-Klasse in diesem Modul implementiert alle erforderlichen Sperrsemantiken. Dies hängt von der Verfügbarkeit der Thread-Unterstützung in Python ab. siehe das Threading-Modul.

3

Wenn Sie auf einem UNIX-basierten System arbeiten, sollten Sie anstelle von Internet-Sockets die Verwendung von UNIX Domain Sockets in Erwägung ziehen.Ich denke, so etwas wie die folgenden funktionieren soll:

>>> # in one window/shell 
>>> import socket 
>>> sd = socket.socket(socket.AF_UNIX) 
>>> sd.bind('/path/to/my/socket') 
>>> sd.listen(5) 
>>> (client,addr) = sd.accept() 
>>> client.recv(1024) 
'hello' 
>>> 

>>> # in a different shell 
>>> import socket 
>>> sd = socket.socket(socket.AF_UNIX) 
>>> sd.connect('/path/to/my/socket') 
>>> sd.send('hello') 
+0

Die Verwendung eines TCP/IP-Sockels auf dem Loopback-Gerät hat den Vorteil (oder den Nachteil, wenn Sie so wollen), dass es beispielsweise über einen SSH-Tunnel zugänglich ist. –

+1

Ein UNIX Domain Socket bietet die gleiche Funktionalität, da er an das Dateisystem gebunden ist. Ich tendiere zu ihnen, weil sie nicht so schwer wie ein IP-Sockel sind. –

0

notionOn TCP/IP-Netzwerke 127.0.0.0/8 ist ein nicht-routeable Netzwerk, so dass Sie nicht in der Lage sein sollten, einen IP-Datagramm schicken bestimmt über 127.0.0.1 eine geroutete Infrastruktur Der Router wird nur das Datagramm verwerfen. Es ist jedoch möglich, Datagramme mit einer Zieladresse von 127.0.0.1 zu konstruieren und zu senden, sodass ein Host im selben Netzwerk (IP-Netzwerk) wie Ihr Host das Datagramm möglicherweise an den TCP/IP-Stack Ihres Hosts senden kann. Dies ist, wo Ihre lokale Feuerstelle ins Spiel kommt. Ihre lokale (Host-) Firewall sollte eine Regel haben, die IP-Datagramme, die für 127.0.0.0/8 bestimmt sind, verwirft, die an eine andere Schnittstelle als lo0 (oder die entsprechende Loopback-Schnittstelle) kommen. Wenn Ihr Host entweder 1) solche Firewall-Regeln installiert hat oder 2) in seinem eigenen Netzwerk existiert (oder mit nur vollständig vertrauenswürdigen Hosts geteilt wird) und hinter einem gut konfigurierten Router, können Sie sicher einfach an 127.0.0.1 binden und ziemlich sicher sein Datagramme, die Sie auf dem Socket empfangen, stammen vom lokalen Computer. Die vorherigen Antworten beziehen sich auf das Öffnen und Binden an 127.0.0.1.

Verwandte Themen