问题
A simple experiment in python (on Windows) shows that I am able to bind to the same port on both the wildcard address and a specific address simultaneously:
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])
Conceptually, they overlap in what they're supposed to cover. Continuing the experiment by connecting to ('127.0.0.1', 13337)
from a different prompt indicates that the more specific socket 'wins' (i.e. 1
is printed).
I'm seeing similar behavior in SOCK_DGRAM
sockets.
My questions are as follows:
- Is this behavior somehow contractual (Winsock, Berkeley Sockets, etc.)?
- How should this behave for multicast sockets?
- How should this behave on *nix systems?
回答1:
What you describe is possible on Windows Server 2003 and later, but only when the two bind()
calls are made by the same user account:
Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE
Enhanced socket security was added with the release of Windows Server 2003. In previous Microsoft server operating system releases, the default socket security easily allowed processes to hijack ports from unsuspecting applications. In Windows Server 2003, sockets are not in a sharable state by default. Therefore, if an application wants to allow other processes to reuse a port on which a socket is already bound, it must specifically enable it. If that is the case, the first socket to call bind on the port must have SO_REUSEADDR set on the socket. The only exception to this case occurs when the second bind call is performed by the same user account that made the original call to bind. This exception exists solely to provide backward compatibility.
The table below describes the behavior that occurs in Windows Server 2003 and later operating systems when a second socket attempts to bind to an address previously bound to by a first socket using specific socket options.
...
The socket binding behavior changes when the socket bind calls are made under different user accounts. The table below specifies the behavior that occurs in Windows Server 2003 and later operating systems when a second socket attempts to bind to an address previously bound to by a first socket using specific socket options and a different user account.
In earlier Windows versions, the behavior was different:
The table below describes the behavior that occurs in Windows XP and earlier when a second socket attempts to bind to an address previously bound to by a first socket using specific socket options.
...
In the case where the first call to bind sets either SO_REUSEADDR or no socket options at all, the second bind call will "hijack" the port and the application will be unable to determine which of the two sockets received specific packets sent to the "shared" port.
来源:https://stackoverflow.com/questions/33618949/binding-to-same-port-using-inaddr-any-and-a-specific-ip-simultaneously