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
Sicher, Duke, ist es auch für frühere Kernel gleich, ich meine Kernel vor Version 3.0?
SP Sandhu
1
Soweit ich weiß, in allen Versionen von Kernel und Libc, PF_ * == AF_ *
Duke
Trifft dies auf Nicht-Linux-Plattformen zu?
Gute Person
1
Ich denke, um sicherzugehen, müssen Sie die enthaltene Header-Datei überprüfen :)
Duke
Auf Ubuntu / Debian fand ich AF-Definitionen in/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
Petr Javorik
48
AF = Adressfamilie
PF = Protokollfamilie
Das heißt, AF_INETbezieht sich auf Adressen aus dem Internet, IP-Adressen speziell. PF_INETbezieht 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_addrFeld einfach Folgendes aus, um es festzulegen:
danke @codemac, ich habe addr.sin_addr.s_addr = inet_addr ("127.0.0.1") verwendet; aber wofür ist inet_pton ()?
SP Sandhu
Auch für Manpages, wenn ich man bind (2) oder man bind () eingebe, gibt terminal unerwartetes Token '(' Fehler aus, während man bind eine Erklärung für bind in bash builtins gibt. Wie man manpage für bind () bekommt. Ich meine bind () Funktion?
SP Sandhu
@ jatt.beas: Die Syntax ist man <section> <topic>zB man 2 bind.
Frerich Raabe
11
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.
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.
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.
Antworten:
Beejs berühmter Netzwerkprogrammierführer gibt eine schöne Erklärung:
quelle
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.
quelle
/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:quelle
man <section> <topic>
zBman 2 bind
.Tatsächlich sind AF_ und PF_ dasselbe. Es gibt einige Wörter auf Wikipedia, die Ihre Verwirrung beseitigen
quelle
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.
quelle
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.
quelle
#define PF_INET AF_INET
bei Cygwinsocket.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.
quelle
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h