为什么redis可以绑定到这个端口,但我不能通过python?

时间:2016-03-27 00:09:28

标签: python sockets redis

我在端口6379上创建了一个服务器套接字,如下所示:

>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s.bind(('localhost', 6379))
>>> s.listen(1)

lsof显示它处于LISTEN状态(为了便于阅读,我删除了一些lsof的列):

Python    13800 IPv4 TCP localhost:6379 (LISTEN)

...现在我将创建一个客户端套接字并连接...

>>> s.connect(('localhost', 6379))

... lsof显示ESTABLISHED ...

Python    13800 IPv4 TCP localhost:6379 (LISTEN)
Python    13838 IPv4 TCP localhost:63075->localhost:6379 (ESTABLISHED)

然后我启动我的redis服务器。这是所有似乎都在使用6379的东西,由lsof提供:

Python    13800 IPv4 TCP localhost:6379 (LISTEN)
Python    13838 IPv4 TCP localhost:63075->localhost:6379 (ESTABLISHED)
redis-ser 13855 IPv6 TCP *:6379 (LISTEN)
redis-ser 13855 IPv4 TCP *:6379 (LISTEN)

我会在redis上添加一些东西来启动另一个连接:

>>> r = redis.StrictRedis('localhost', 6379)
>>> r.set('foo', 'bar')

......我可以在lsof中看到......

Python    13800 IPv4 TCP localhost:6379 (LISTEN)
Python    13838 IPv4 TCP localhost:63075->localhost:6379 (ESTABLISHED)
redis-ser 13855 IPv6 TCP *:6379 (LISTEN)
redis-ser 13855 IPv4 TCP *:6379 (LISTEN)
redis-ser 13855 IPv6 TCP localhost:6379->localhost:63084 (ESTABLISHED)

所以我的问题是......如果我按相反的顺序这样做,例如首先运行“redis-server”,然后尝试将套接字绑定到端口6379,我得到一个“已经在使用的地址”错误。

为什么在Python已经允许的情况下允许redis使用该端口,但反之则不然?

例如......

redis --port 1234

...工作正常,但是如果我在运行时尝试创建一个Python套接字:

>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s.bind(('localhost', 1234))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 228, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 48] Address already in use

1 个答案:

答案 0 :(得分:1)

两种可能性:

  1. 你会注意到redis被绑定到&#34; *&#34;而python绑定到localhost。因此当第二次启动redis时,它仍然允许绑定,因为它更普遍地监听:可能有一个传入连接不是来自localhost,而redis可以处理而不是python。但是当redis首先监听时,现在没有可以由不同程序处理的地址,因此无法在同一端口上打开。您可以阅读有关UNIX程序route的更多信息以获取详细信息。

  2. 有一个SO_REUSEPORT选项,允许多个服务器在同一端口上侦听,并将传入连接发送到随机服务器。 Can two applications listen to the same port? redis可能正在使用它来支持负载平衡。如果python程序没有指定这个标志,我希望它的监听被拒绝。