Qual è la differenza tra AF_INET e PF_INET nella programmazione socket?


205

Qual è la differenza tra AF_INET e PF_INET nella programmazione socket?

Sono confuso tra l'utilizzo di AF_INET e PF_INET in socket()e bind().

Inoltre, come fornire l'indirizzo IP nel sin_addrcampo?


Basta cercare in rete: un risultato è questo
Op De Cirkel,

Mi chiedevo anche questo. Sembrano essere usati in modo intercambiabile nella chiamata socket tra diversi programmatori.
Matt,

@MattH Entrambi sono gli stessi dei nuovi kernel Linux. Puoi trovare lo stesso nella risposta di Duke qui sotto.
SP Sandhu,

Risposte:


250

La famosa guida alla programmazione di rete di Beej offre una bella spiegazione:

In alcuni documenti, vedrai la menzione di un mistico "PF_INET". Questa è una strana bestia eterea che raramente si vede in natura, ma potrei anche chiarirla un po 'qui. Molto tempo fa, si pensava che forse una famiglia di indirizzi (che cosa significa "AF" in "AF_INET") potesse supportare diversi protocolli a cui faceva riferimento la loro famiglia di protocolli (che cosa significa "PF" in "PF_INET" ).
Non è successo. Oh bene. Quindi la cosa giusta da fare è usare AF_INET in struct sockaddr_in e PF_INET nella tua chiamata a socket (). In pratica, puoi usare AF_INET ovunque. E, poiché è quello che fa W. Richard Stevens nel suo libro, è quello che farò qui.


68

Ho scoperto nel codice sorgente del kernel Linux che PF_INET e AF_INET sono uguali. Il seguente codice proviene dal file include / linux / socket.h , linea 204 dell'albero del kernel 3.2.21 di Linux.

/* Protocol families, same as address families. */
...
#define PF_INET     AF_INET

certo Duke, è lo stesso anche per i kernel precedenti, intendo i kernel precedenti alla versione 3.0?
SP Sandhu,

1
Per quanto ne so, in tutte le versioni di kernel e libc, PF_ * == AF_ *
Duke

È vero su piattaforme non Linux?
Brava persona,

1
Penso per essere sicuro, è necessario controllare il file di intestazione incluso :)
Duke,

Su Ubuntu / Debian ho trovato le definizioni AF in/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
Petr Javorik,

48
  • AF = Famiglia di indirizzi
  • PF = Famiglia protocollo

Significato, si AF_INETriferisce a indirizzi da Internet, indirizzi IP specifici. PF_INETsi riferisce a qualsiasi cosa nel protocollo, generalmente socket / porte.

Considera di leggere le pagine man per socket (2) e bind (2) . Per il sin_addrcampo, basta fare qualcosa di simile al seguente per impostarlo:

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

grazie @codemac, ho usato addr.sin_addr.s_addr = inet_addr ("127.0.0.1"); ma a cosa serve inet_pton ()?
SP Sandhu,

anche per le pagine man, quando scrivo man bind (2) o man bind (), il terminale dà un token imprevisto '(' errore mentre man bind dà una spiegazione del bind nei builtin bash. Come ottenere man page per bind (). Funzione bind ()?
SP Sandhu,

@ jatt.beas: la sintassi è man <section> <topic>, ad es man 2 bind.
Frerich Raabe,

11

In effetti, AF_ e PF_ sono la stessa cosa. Ci sono alcune parole su Wikipedia per cancellare la tua confusione

Il concetto di design originale dell'interfaccia socket si distingueva tra i tipi di protocollo (famiglie) e i tipi di indirizzo specifici che ciascuno può utilizzare. Si pensava che una famiglia di protocolli potesse avere diversi tipi di indirizzo. I tipi di indirizzo sono stati definiti da costanti simboliche aggiuntive, usando il prefisso AF_ anziché PF_. Gli identificatori AF_ sono destinati a tutte le strutture di dati che si occupano specificamente del tipo di indirizzo e non della famiglia di protocolli. Tuttavia, questo concetto di separazione del protocollo e del tipo di indirizzo non ha trovato supporto all'implementazione e le costanti AF_ sono state semplicemente definite dal corrispondente identificatore di protocollo, rendendo la distinzione tra costanti AF_ contro PF_ un argomento tecnico senza conseguenze pratiche significative. In effetti, esiste molta confusione nell'uso corretto di entrambe le forme.


4

AF_INET = Formato indirizzo, Internet = Indirizzi IP

PF_INET = Formato pacchetto, Internet = IP, TCP / IP o UDP / IP

AF_INET è la famiglia di indirizzi utilizzata per il socket che stai creando (in questo caso un indirizzo del protocollo Internet). Il kernel Linux, ad esempio, supporta altre 29 famiglie di indirizzi come socket UNIX e IPX e anche comunicazioni con IRDA e Bluetooth (AF_IRDA e AF_BLUETOOTH, ma è dubbio che le userete a un livello così basso).

Per la maggior parte, attenersi a AF_INET per la programmazione dei socket su una rete è l'opzione più sicura.

Significato, AF_INET si riferisce a indirizzi da Internet, indirizzi IP specifici.

PF_INET si riferisce a qualsiasi cosa nel protocollo, generalmente socket / porte.


3

Ci sono situazioni in cui conta.

Se si passa AF_INET a socket()in Cygwin, il socket può essere ripristinato o meno in modo casuale. Il passaggio di PF_INET garantisce che la connessione funzioni correttamente.

Cygwin è certamente un gran casino per la programmazione dei socket, ma è un caso reale in cui AF_INET e PF_INET non sono identici.


6
Spiega per favore. Lo trovo #define PF_INET AF_INETin Cygwin socket.h.
Marchese di Lorne,

3

Controllare il file header per risolvere il problema. Si può verificare la presenza del compilatore di sistema.

Per il mio sistema, AF_INET == PF_INET

AF == Famiglia di indirizzi e PF == Famiglia di protocolli

Famiglie di protocolli, come le famiglie di indirizzi.

inserisci qui la descrizione dell'immagine


1
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h
Noobninja,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.