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_addr
campo?
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_addr
campo?
Respostas:
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.
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
/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
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.
Considere ler as páginas de manual para socket (2) e bind (2) . Para o sin_addr
campo, faça algo como o seguinte para defini-lo:
struct sockaddr_in addr;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
man <section> <topic>
, por exemplo man 2 bind
.
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.
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.
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.
#define PF_INET AF_INET
no Cygwin's socket.h
.
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.
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h