Why do开发者_StackOverflow中文版es struct sockaddr
contain an address family field? Isn't the address family already fixed with the call to socket()
?
sockaddr
is used in more places than just connect
and bind
, including places where you don't have some external knowledge of the address family involved - getaddrinfo
being one.
Additionally, whilst I don't believe the following equates to practice anywhere, I can see it having been in the eye of whoever designed this stuff originally: the call to socket()
defines the protocol family. sockaddr
contains the address family. In practice, I believe these are always the same, but you could theoretically have a protocol capable of supporting two different address types.
EDIT: There's another way that the parameter is useful. If you're using datagram (UDP) sockets and you have a socket in a "connected" state with a default destination address, you can clear out that address by calling connect()
with a sockaddr
with sa_family
set to AF_UNSPEC
.
If you look at the getaddrinfo
interface, which is the only modern correct way to convert between interchange representations of addresses (names or numeric addresses) and the sockaddr
structures, I think you'll see why it's needed.
With that said, the whole struct sockaddr
stuff is a huge mess of misdesigns, especially the userspace endian conversion.
Another good instance of why the sa_family
field is needed is the getsockname
and getpeername
interfaces. If the program inherited the file descriptor from another program, and doesn't already know what type of socket it is, it needs to be able to determine that in order to make new connections or even convert the address to a representation suitable for interchange.
If you look at the network code for 4.2BSD, where the sockets interface originated, you'll see that the sockaddr
is passed to the network interface drivers but the socket fd is not.
The sa_family field is used to tell what type of address will be in the sa_data field. In a lot of applications, the address family is assumed to be IPV4. However, many applications also support IPV6.
精彩评论