python 创建仅限本地主机连接的套接字
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2135595/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Creating a socket restricted to localhost connections only
提问by Dr. Johnson
I have a python program with many threads. I was thinking of creating a socket, 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?
我有一个有很多线程的 python 程序。我正在考虑创建一个套接字,将其绑定到本地主机,并将线程读/写到这个中心位置。但是我不希望这个套接字对网络的其余部分开放,只127.0.0.1
应该接受来自的连接。我将如何做到这一点(在 Python 中)?这是一个合适的设计吗?或者有什么更优雅的东西?
回答by Greg Hewgill
回答by petantik
http://www.amk.ca/python/howto/sockets/
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.
我们使用 socket.gethostname() 以便套接字对外界可见。如果我们使用 s.bind(('', 80)) 或 s.bind(('localhost', 80)) 或 s.bind(('127.0.0.1', 80)) 我们仍然会有一个“服务器" 插座,但只有在同一台机器上才能看到的插座。
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
下面似乎有一个 python 配方链接,它进行一些线程间通信
http://code.activestate.com/recipes/491281/
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"
文章不正确,正如所指出的“ s.bind(('', 80)) will bind to INADDR_ANY”
回答by D.Shawley
If you are running on a UNIX-based system, you might want to consider using UNIX Domain Socketsinstead of Internet sockets. I think something like the following should work:
如果您在基于 UNIX 的系统上运行,您可能需要考虑使用UNIX 域套接字而不是 Internet 套接字。我认为类似以下内容应该有效:
>>> # 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')
回答by Micha? Marczyk
You might want to use the queue modulefrom the standard library instead. It's designed specifically to facilitate communication between threads. A quote from the docs:
您可能希望改用标准库中的queue 模块。它专为促进线程之间的通信而设计。来自文档的引用:
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.
Queue 模块实现了多生产者、多消费者队列。当信息必须在多个线程之间安全交换时,它在线程编程中特别有用。此模块中的 Queue 类实现了所有必需的锁定语义。这取决于 Python 中线程支持的可用性;见线程模块。
回答by nos
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.
如果你做 sock.bind((port,'127.0.0.1')) 它只会在本地主机上监听,而不是在其他接口上,所以这就是你所需要的。
回答by Dom Brezinski
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.
在 TCP/IP 网络上,127.0.0.0/8 是一个不可路由的网络,因此您应该无法通过路由基础设施发送目的地为 127.0.0.1 的 IP 数据报。路由器只会丢弃数据报。但是,可以构造和发送目标地址为 127.0.0.1 的数据报,因此与您的主机位于同一网络(IP 网络感知)上的主机可能会将数据报发送到您主机的 TCP/IP 堆栈。这是您的本地防火墙发挥作用的地方。您的本地(主机)防火墙应该有一个规则,可以丢弃发往 127.0.0.0/8 的 IP 数据报,这些数据报进入除 lo0(或等效的环回接口)以外的任何接口。如果您的主机 1) 具有此类防火墙规则或 2) 存在于其自己的网络上(或仅与完全信任的主机共享)并在配置良好的路由器之后,您可以安全地绑定到 127.0.0.1 并且相当确定您在套接字上收到的任何数据报都来自本地机器。先前的答案解决了如何打开和绑定到 127.0.0.1。