python 中的一个简单实验(在 Windows 上)表明我能够同时绑定到通配符地址和特定地址上的同一端口:
import socket
import select
MY_PORT = 13337
sany = socket.socket()
sany.bind(('', MY_PORT))
sany.listen(0)
sloc = socket.socket()
sloc.bind(('127.0.0.1', MY_PORT))
sloc.listen(0)
socks = [sany, sloc]
ready, _, _ = select.select(socks, [], [])
print socks.index(ready[0])
从概念上讲,它们在应该涵盖的内容上有所重叠。连接到继续实验('127.0.0.1', 13337)
来自不同的提示表明更具体的套接字“获胜”(即1
被打印)。
我看到类似的行为SOCK_DGRAM
插座。
我的问题如下:
- 这种行为是否具有某种契约性(Winsock、Berkeley Sockets 等)?
- 对于多播套接字来说,这应该如何表现?
- 这在 *nix 系统上应该如何表现?
您所描述的内容在 Windows Server 2003 及更高版本上是可能的,但只有当两者bind()
调用由同一用户帐户进行:
使用 SO_REUSEADDR 和 SO_EXCLUSIVEADDRUSE https://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx
Windows Server 2003 的发布增加了增强的套接字安全性。在以前的 Microsoft 服务器操作系统版本中,默认的套接字安全性很容易允许进程从毫无戒心的应用程序劫持端口。在 Windows Server 2003 中,默认情况下套接字不处于可共享状态。因此,如果应用程序想要允许其他进程重用已绑定套接字的端口,则必须专门启用它。如果是这种情况,在端口上调用绑定的第一个套接字必须在该套接字上设置 SO_REUSEADDR。这种情况的唯一例外是当第二次绑定调用由发出原始绑定调用的同一用户帐户执行时。此异常的存在只是为了提供向后兼容性。
下表描述了当第二个套接字尝试绑定到先前由第一个套接字使用特定套接字选项绑定到的地址时,Windows Server 2003 及更高版本的操作系统中发生的行为。
...
当在不同的用户帐户下进行套接字绑定调用时,套接字绑定行为会发生变化。下表指定了当第二个套接字尝试使用特定套接字选项和不同的用户帐户绑定到先前由第一个套接字绑定的地址时,在 Windows Server 2003 及更高版本的操作系统中发生的行为。
在早期的 Windows 版本中,行为有所不同:
下表描述了在 Windows XP 及更早版本中当第二个套接字尝试绑定到先前由第一个套接字使用特定套接字选项绑定的地址时发生的行为。
...
在第一次调用绑定设置 SO_REUSEADDR 的情况下或者根本没有套接字选项,第二个绑定调用将“劫持”端口,应用程序将无法确定两个套接字中的哪一个接收到发送到“共享”端口的特定数据包。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)