Was ist der Unterschied zwischen AF_INET und PF_INET bei der Socket-Programmierung?
Ich bin verwirrt zwischen der Verwendung von AF_INET und PF_INET in socket()
und bind()
.
Wie kann man im sin_addr
Feld eine IP-Adresse angeben?
Was ist der Unterschied zwischen AF_INET und PF_INET bei der Socket-Programmierung?
Ich bin verwirrt zwischen der Verwendung von AF_INET und PF_INET in socket()
und bind()
.
Wie kann man im sin_addr
Feld eine IP-Adresse angeben?
Antworten:
Beejs berühmter Netzwerkprogrammierführer gibt eine schöne Erklärung:
In einigen Dokumentationen wird ein mystisches "PF_INET" erwähnt. Dies ist ein seltsames ätherisches Tier, das in der Natur selten zu sehen ist, aber ich könnte es hier genauso gut ein wenig klären. Vor langer Zeit wurde angenommen, dass eine Adressfamilie (wofür der "AF" in "AF_INET" steht) möglicherweise mehrere Protokolle unterstützt, auf die von ihrer Protokollfamilie verwiesen wird (wofür der "PF" in "PF_INET" steht ).
Das ist nicht passiert. Naja. Das Richtige ist also, AF_INET in Ihrer Struktur sockaddr_in und PF_INET in Ihrem Aufruf von socket () zu verwenden. In der Praxis können Sie AF_INET jedoch überall verwenden. Und da W. Richard Stevens dies in seinem Buch tut, werde ich das hier tun.
Ich habe im Linux-Kernel-Quellcode festgestellt, dass PF_INET und AF_INET identisch sind. Der folgende Code stammt aus der Datei include / linux / socket.h , Zeile 204 des Linux-Kernel 3.2.21-Baums.
/* Protocol families, same as address families. */
...
#define PF_INET AF_INET
/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
Das heißt, AF_INET
bezieht sich auf Adressen aus dem Internet, IP-Adressen speziell. PF_INET
bezieht sich auf alles im Protokoll, normalerweise Sockets / Ports.
Lesen Sie die Manpages für Socket (2) und Binden (2) . Führen Sie für das sin_addr
Feld einfach Folgendes aus, um es festzulegen:
struct sockaddr_in addr;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
man <section> <topic>
zB man 2 bind
.
Tatsächlich sind AF_ und PF_ dasselbe. Es gibt einige Wörter auf Wikipedia, die Ihre Verwirrung beseitigen
Das ursprüngliche Designkonzept der Socket-Schnittstelle unterschied zwischen Protokolltypen (Familien) und den spezifischen Adresstypen, die jeweils verwendet werden können. Es wurde ins Auge gefasst, dass eine Protokollfamilie mehrere Adresstypen haben kann. Adresstypen wurden durch zusätzliche symbolische Konstanten definiert, wobei das Präfix AF_ anstelle von PF_ verwendet wurde. Die AF_-IDs sind für alle Datenstrukturen vorgesehen, die sich speziell mit dem Adresstyp und nicht mit der Protokollfamilie befassen. Dieses Konzept der Trennung von Protokoll- und Adresstyp hat jedoch keine Implementierungsunterstützung gefunden, und die AF_-Konstanten wurden einfach durch die entsprechende Protokollkennung definiert, was die Unterscheidung zwischen AF_- und PF_-Konstanten zu einem technischen Argument ohne wesentliche praktische Konsequenz macht. In der Tat besteht viel Verwirrung bei der richtigen Verwendung beider Formen.
AF_INET = Adressformat, Internet = IP-Adressen
PF_INET = Paketformat, Internet = IP, TCP / IP oder UDP / IP
AF_INET ist die Adressfamilie, die für den von Ihnen erstellten Socket verwendet wird (in diesem Fall eine Internetprotokolladresse). Der Linux-Kernel unterstützt beispielsweise 29 andere Adressfamilien wie UNIX-Sockets und IPX sowie die Kommunikation mit IRDA und Bluetooth (AF_IRDA und AF_BLUETOOTH, aber es ist zweifelhaft, ob Sie diese auf einer so niedrigen Ebene verwenden).
Zum größten Teil ist es die sicherste Option, bei AF_INET für die Socket-Programmierung über ein Netzwerk zu bleiben.
Das heißt, AF_INET bezieht sich auf Adressen aus dem Internet, speziell auf IP-Adressen.
PF_INET bezieht sich auf alles im Protokoll, normalerweise Sockets / Ports.
Es gibt Situationen, in denen es darauf ankommt.
Wenn Sie AF_INET socket()
in Cygwin übergeben, wird Ihr Socket möglicherweise zufällig zurückgesetzt oder nicht. Durch Übergeben von PF_INET wird sichergestellt, dass die Verbindung ordnungsgemäß funktioniert.
Cygwin ist zwar ein großes Durcheinander für die Socket-Programmierung, aber es ist ein realer Fall, in dem AF_INET und PF_INET nicht identisch sind.
#define PF_INET AF_INET
bei Cygwin socket.h
.
Das Überprüfen der Header-Datei löst das Problem. Man kann dort nach System-Compiler suchen.
Für mein System AF_INET == PF_INET
AF == Adressfamilie und PF == Protokollfamilie
Protokollfamilien wie Adressfamilien.
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h