Was ist der Unterschied zwischen AF_INET und PF_INET bei der Socket-Programmierung?


205

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_addrFeld eine IP-Adresse angeben?


Suchen Sie einfach im Internet: Ein Ergebnis ist dies
Op De Cirkel

Ich habe mich auch gefragt. Sie scheinen im Socket-Aufruf zwischen verschiedenen Codierern austauschbar verwendet zu werden.
Matt

@MattH Beide sind identisch mit den neuen Linux-Kerneln. Sie finden das gleiche in Dukes Antwort unten.
SP Sandhu

Antworten:


250

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.


68

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:

struct sockaddr_in addr;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); 

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.


4

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.


3

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.


6
Bitte erkläre. Ich finde #define PF_INET AF_INETbei Cygwin socket.h.
Marquis von Lorne

3

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.

Geben Sie hier die Bildbeschreibung ein


1
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h
Noobninja
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.