Was ist der Zweck der sa_data Feld in einer sockaddr?
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
Die tatsächliche Struktur übergeben, für die die ADR-argument wird, hängt von der Adresse der Familie. Die sockaddr-Struktur ist definiert als so etwas wie:
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
}
Also für eine IPv4-Adresse (AF_INET), der eigentlichen struct übergeben wird, ist dies:
/* Source http://linux.die.net/man/7/ip */
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */
in_port_t sin_port; /* port in network byte order */
struct in_addr sin_addr; /* internet address */
};
/* Internet address. */
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
Tut der bind-code Lesen Sie die sockaddr.sa_family
Wert und je nach dem Wert, den es findet, es wird dann warf die sockaddr
struct in das entsprechende struct wie sockaddr_in
?
Warum ist die sa_data
set zu 14 Zeichen? Wenn ich verstehe richtig, die sa_data
Feld ist einfach ein Feld, das große genug Speicherplatz, um alle passen-Adresse familienformen? Vermutlich sind die original-Designer erwartet, dass 14 Charaktere wäre breit genug, um alle zukünftigen Arten.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Entsprechend der glibc-Handbuch:
Und die Die FreeBSD-Entwickler-Handbuch erwähnt die folgenden:
Ja, die
sa_family
Feld wird verwendet, um erkennen zu behandeln, wie das struct übergeben (die cast aufstruct sockaddr*
in einem Aufruf von bind). Lesen Sie mehr darüber, wie es funktioniert auch in einer Die FreeBSD-Entwickler-Handbuch.Und tatsächlich gibt es "polymorph" (sub -) Typen von
sockaddr
, in denensa_data
enthält mehr als 16 bytes, zum Beispiel:Den
sockaddr
struct verwendet wird, als tagged union. Durch das Lesen dersa_family
Feld, es kann geworfen werden, um eine Struktur, die der richtigen form.14 bytes ist beliebig. Es ist groß genug, um IPv4-Adressen, aber nicht groß genug, um IPv6-Adressen. Es gibt auch eine
sockaddr_storage
Struktur, die ist groß genug für Sie beide. Lesen Sie die Microsoft docs auf SOCKADDR_STORAGE, es kommt auf 128 bytes, also viel größer als notwendig für IPv6. Die überprüfung einige Linux-Header, so scheint es zumindest, dass die großen auch da.Referenz, die IPv6-Struktur ist:
Wie Sie sehen können, die 16-byte -
s6_addr
Feld ist bereits größer als die 14-byte -sa_data
Feld auf seine eigene. Gesamtgröße nach dersa_family
Feld ist 26 bytes.