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)
继续实验表明更具体的套接字'wins'(即打印1
)。
我在SOCK_DGRAM
套接字中看到了类似的行为。
我的问题如下:
答案 0 :(得分:3)
您在Windows Server 2003及更高版本中可以描述的内容,但仅当同一用户帐户发出两个bind()
来电时才会这样:
Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE
随着Windows Server 2003的发布,增加了套接字安全性。在以前的Microsoft服务器操作系统版本中,默认的套接字安全性很容易允许进程从不知情的应用程序中劫持端口。在Windows Server 2003中,默认情况下套接字不处于可共享状态。因此,如果应用程序希望允许其他进程重用已绑定套接字的端口,则必须专门启用它。如果是这种情况,则在端口上调用bind的第一个套接字必须在套接字上设置SO_REUSEADDR。 这种情况的唯一例外是当第二个绑定调用由进行绑定的原始调用的同一用户帐户执行时发生。此异常仅用于提供向后兼容性。
下表描述了当第二个套接字尝试使用特定套接字选项绑定到先前由第一个套接字绑定的地址时,Windows Server 2003及更高版本操作系统中发生的行为。
...
在不同用户帐户下进行套接字绑定调用时,套接字绑定行为会发生更改。下表指定第二个套接字尝试绑定时Windows Server 2003及更高版本操作系统中发生的行为到先前使用特定套接字选项和不同用户帐户绑定到第一个套接字的地址。
在早期的Windows版本中,行为有所不同:
下表描述了当第二个套接字尝试使用特定套接字选项绑定到先前由第一个套接字绑定的地址时,Windows XP及更早版本中发生的行为。
...
如果第一次调用bind设置SO_REUSEADDR 或根本没有设置套接字选项,则第二次绑定调用将"劫持"端口和应用程序将无法确定两个套接字中的哪一个接收到发送到"共享"的特定数据包。端口。