簡體   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