Qual é a diferença entre AF_INET e PF_INET na programação de soquetes?

205

Qual é a diferença entre AF_INET e PF_INET na programação de soquetes?

Estou confuso entre usar AF_INET e PF_INET em socket()e bind().

Além disso, como dar o endereço IP no sin_addrcampo?

SP Sandhu
fonte
Basta pesquisar na net: um resultado é este
Op De Cirkel
Eu estive pensando isso também. Eles parecem se acostumar de maneira intercambiável na chamada de soquete entre diferentes codificadores.
21812 Matt
@ MattH Ambos são iguais aos novos kernels do Linux. Você pode encontrar o mesmo na resposta de Duke abaixo.
SP Sandhu

Respostas:

250

O famoso guia de programação de rede de Beej fornece uma boa explicação:

Em alguma documentação, você verá a menção de um "PF_INET" místico. Este é um animal etéreo estranho que raramente é visto na natureza, mas eu poderia esclarecer um pouco aqui. Há muito tempo, pensava-se que talvez uma família de endereços (o que significa "AF" em "AF_INET") possa suportar vários protocolos referenciados por sua família de protocolos (o que significa "PF" em "PF_INET" )
Isso não aconteceu. Ah bem. Portanto, a coisa certa a fazer é usar AF_INET em sua estrutura sockaddr_in e PF_INET em sua chamada para socket (). Mas, na prática, você pode usar o AF_INET em qualquer lugar. E, como é o que W. Richard Stevens faz em seu livro, é o que farei aqui.

Damon
fonte
68

Eu encontrei no código fonte do kernel Linux que PF_INET e AF_INET são os mesmos. O código a seguir é do arquivo include / linux / socket.h , linha 204 da árvore do kernel do Linux 3.2.21.

/* Protocol families, same as address families. */
...
#define PF_INET     AF_INET
Duque
fonte
Claro Duke, é o mesmo para os kernels anteriores também, quero dizer, os kernels anteriores à versão 3.0?
SP Sandhu
1
Até onde sei, em todas as versões do kernel e libc, PF_ * == AF_ *
Duke
Isso é verdade em plataformas não-linux?
Good Person
1
Eu acho que para ter certeza, você precisa verificar o arquivo de cabeçalho incluído :)
Duke
No Ubuntu / Debian achei definições AF em/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
Petr Javorik
48
  • AF = Família de Endereços
  • PF = Família de Protocolos

Significado, AF_INETrefere-se a endereços da Internet, endereços IP especificamente. PF_INETrefere-se a qualquer coisa no protocolo, geralmente soquetes / portas.

Considere ler as páginas de manual para socket (2) e bind (2) . Para o sin_addrcampo, faça algo como o seguinte para defini-lo:

struct sockaddr_in addr;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); 
codemac
fonte
obrigado @codemac, usei addr.sin_addr.s_addr = inet_addr ("127.0.0.1"); mas para que serve inet_pton ()?
SP Sandhu
também para man pages, quando digito man bind (2) ou man bind (), o terminal fornece um token inesperado '(' erro enquanto o man bind dá uma explicação sobre o bind em bash builtins. Como obter a página do manual para bind (). Função bind ()?
SP Sandhu
@ jatt.beas: A sintaxe é man <section> <topic>, por exemplo man 2 bind.
Frerich Raabe
11

De fato, AF_ e PF_ são a mesma coisa. Existem algumas palavras na Wikipedia que esclarecerão sua confusão

O conceito de design original da interface do soquete distinguia entre os tipos de protocolo (famílias) e os tipos de endereço específicos que cada um pode usar. Foi previsto que uma família de protocolos possa ter vários tipos de endereços. Os tipos de endereço foram definidos por constantes simbólicas adicionais, usando o prefixo AF_ em vez de PF_. Os identificadores AF_ são destinados a todas as estruturas de dados que lidam especificamente com o tipo de endereço e não a família de protocolos. No entanto, esse conceito de separação de protocolo e tipo de endereço não encontrou suporte à implementação e as constantes AF_ foram simplesmente definidas pelo identificador de protocolo correspondente, tornando a distinção entre constantes AF_ versus PF_ um argumento técnico sem conseqüências práticas significativas. De fato, existe muita confusão no uso adequado de ambas as formas.

firo
fonte
4

AF_INET = Formato do endereço, Internet = Endereços IP

PF_INET = Formato de pacote, Internet = IP, TCP / IP ou UDP / IP

AF_INET é a família de endereços usada para o soquete que você está criando (nesse caso, um endereço de protocolo da Internet). O kernel do Linux, por exemplo, suporta 29 outras famílias de endereços, como soquetes UNIX e IPX, e também comunicações com IRDA e Bluetooth (AF_IRDA e AF_BLUETOOTH, mas é duvidoso que você as use em um nível tão baixo).

Na maioria das vezes, seguir o AF_INET para programação de soquetes em uma rede é a opção mais segura.

Significado, AF_INET refere-se a endereços da Internet, endereços IP especificamente.

PF_INET refere-se a qualquer coisa no protocolo, geralmente soquetes / portas.

DINO U
fonte
3

Existem situações em que isso importa.

Se você passar AF_INET para socket()no Cygwin, seu soquete poderá ou não ser redefinido aleatoriamente. Passar PF_INET garante que a conexão funcione corretamente.

O Cygwin é uma grande bagunça na programação de soquetes, mas é um caso no mundo real em que AF_INET e PF_INET não são idênticos.

FlyingJester
fonte
6
Por favor explique. Eu encontro #define PF_INET AF_INETno Cygwin's socket.h.
Marquês de Lorne
3

Verificar o arquivo de cabeçalho resolve o problema. Pode-se verificar o compilador do sistema.

Para o meu sistema, AF_INET == PF_INET

AF == Família de endereços e PF == Família de protocolos

Famílias de protocolo, o mesmo que famílias de endereços.

insira a descrição da imagem aqui

Rishap Singh
fonte
1
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h
Noobninja 31/10/19