繁体   English   中英

为什么不能同时绑定到0.0.0.0:80和192.168.1.1:80?

[英]why can't bind to 0.0.0.0:80 and 192.168.1.1:80 simultaneously?

我的python测试代码:

import socket

s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s1.bind(('192.168.1.1', 80)) 
s1.listen(5)

s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.bind(('0.0.0.0', 80)) 
s2.listen(5)

我收到了这个错误:

fpemud-workstation test # ./test.py
Traceback (most recent call last):
  File "./test.py", line 11, in <module>
    s2.bind(('0.0.0.0', 80)) 
  File "/usr/lib64/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 98] Address already in use

192.168.1.1是我的eth0接口的ip地址。
我认为0.0.0.0:80和192.168.1.1:80应该能够共存。
带有dst-addr 192.168.1.1的数据包进入套接字s1,带有其他dst-addr的数据包进入套接字s2。

您无法绑定到0.0.0.0:80和端口80上的任何其他IP,因为0.0.0.0涵盖了计算机上存在的每个IP,包括您的192.168.1.1地址。 它并不意味着“任何其他目的地地址”,它意味着“此框中的所有接口”。

因为这是一个矛盾的术语。 0.0.0.0表示“接受来自任何本地IP地址的连接”。 192.168.1.1表示“仅接受发送到192.168.1.1的连接”。 如果有人连接到192.168.1.1,您到底会发生什么?

尽管其他答案已经说过,但这应该是可能的 - 只是bind工作的方式依赖于实现。

例如,在Windows上,您的代码可能会正常工作。 在某些* nix操作系统上,我相信您可以通过设置SO_REUSEADDR套接字选项来使其工作。 在Linux上,我已经能够使用SO_REUSEPORT套接字选项使其工作,但仅限于内核版本3.9或更高版本。

不幸的是,当前版本的python不直接支持SO_REUSEPORT属性,因此我们必须手动定义它。

基本上你的代码应该是这样的:

# This adds support for the SO_REUSEPORT constant if not already defined.
if not hasattr(socket, 'SO_REUSEPORT'):
  socket.SO_REUSEPORT = 15

s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s1.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s1.bind(('192.168.1.1', 80)) 
s1.listen(5)

s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s2.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s2.bind(('0.0.0.0', 80)) 
s2.listen(5)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM