开发者

Creating a socket restricted to localhost connections only

开发者 https://www.devze.com 2022-12-17 07:35 出处:网络
I have a python program with many threads. I was thinking of creating a socke开发者_运维问答t, bind it to localhost, and have the threads read/write to this central location. However I do not want thi

I have a python program with many threads. I was thinking of creating a socke开发者_运维问答t, bind it to localhost, and have the threads read/write to this central location. However I do not want this socket open to the rest of the network, just connections from 127.0.0.1 should be accepted. How would I do this (in Python)? And is this a suitable design? Or is there something a little more elegant?


Given a socket created with socket.socket(), you can use bind() before listening:

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

Using the address 127.0.0.1 indicates that the socket should bind to the local interface only.


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

Shows some socket example. This tidbit is interesting to you I think

we used socket.gethostname() so that the socket would be visible to the outside world. If we had used s.bind(('', 80)) or s.bind(('localhost', 80)) or s.bind(('127.0.0.1', 80)) we would still have a "server" socket, but one that was only visible within the same machine.

I guess there is your answer (see below for correction)

As to the validity of using this method for thread communications. I'm not sure how well this handles multiple threads and reading/writing

EDIT

There seems to be a python recipe linked below that does some inter-thread communication

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

Have fun!

EDIT

The article is incorrect and as pointed out "s.bind(('', 80)) will bind to INADDR_ANY"


If you are running on a UNIX-based system, you might want to consider using UNIX Domain Sockets instead of Internet sockets. I think something like the following should work:

>>> # 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')


You might want to use the queue module from the standard library instead. It's designed specifically to facilitate communication between threads. A quote from the docs:

The Queue module implements multi-producer, multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads. The Queue class in this module implements all the required locking semantics. It depends on the availability of thread support in Python; see the threading module.


notionOn TCP/IP networks 127.0.0.0/8 is a non-routeable network, so you should not be able to send an IP datagram destined to 127.0.0.1 across a routed infrastructure. The router will just discard the datagram. However, it is possible to construct and send datagrams with a destination address of 127.0.0.1, so a host on the same network (IP sense of network) as your host could possibly get the datagram to your host's TCP/IP stack. This is where your local firewal comes into play. Your local (host) firewall should have a rule that discards IP datagrams destined for 127.0.0.0/8 coming into any interface other than lo0 (or the equivalent loopback interface). If your host either 1) has such firewall rules in place or 2) exists on its own network (or shared with only completely trusted hosts) and behind a well configured router, you can safely just bind to 127.0.0.1 and be fairly certain any datagrams you receive on the socket came from the local machine. The prior answers address how to open and bind to 127.0.0.1.


If you do sock.bind((port,'127.0.0.1')) it will only listen on localhost, and not on other interfaces, so that's all you need.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号