我的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 :(得分:13)
您无法绑定到0.0.0.0:80和端口80上的任何其他IP,因为0.0.0.0涵盖了计算机上存在的每个IP,包括您的192.168.1.1地址。它并不代表任何其他目的地地址,它表示此框中的所有接口都是&#39;。
答案 1 :(得分:1)
因为这是一个矛盾的术语。 0.0.0.0表示“接受来自任何本地IP地址的连接”。 192.168.1.1表示“仅接受发送到192.168.1.1的连接”。如果有人连接到192.168.1.1,您期望发生什么?
答案 2 :(得分: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)