【问题标题】:why can redis bind to this port, but I can't via python?为什么redis可以绑定到这个端口,但我不能通过python?
【发布时间】:2016-03-27 00:09:27
【问题描述】:

我在 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

【问题讨论】:

  • 编辑标题说“绑定”而不是“连接”?

标签: python sockets redis


【解决方案1】:

两种可能:

  1. 您会注意到,redis 绑定到“*”,而 python 绑定到 localhost。所以当 redis 第二次启动时,它仍然被允许绑定,因为它更广泛地监听:可能有一个不是来自本地主机的传入连接,redis 可以处理它而不是 python。但是当redis先监听的时候,现在已经没有其他程序可以处理的地址了,所以不可能在同一个端口上打开。您可以阅读更多关于 UNIX 程序 route 的详细信息。

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

【讨论】:

    猜你喜欢
    • 2020-12-25
    • 1970-01-01
    • 2012-01-07
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多