ソケットプログラミングにおけるAF_INETとPF_INETの違いは何ですか?


205

ソケットプログラミングにおけるAF_INETとPF_INETの違いは何ですか?

とでAF_INETとPF_INETを使用するのが混乱しsocket()ていbind()ます。

また、sin_addrフィールドにIPアドレスを与える方法は?


ネットを検索するだけです。1つの結果はこれです
Op De Cirkel '18

私もこれを考えていました。それらは、異なるコーダー間のソケット呼び出しで互換的に使用されるようです。
マット

@MattHどちらも新しいLinuxカーネルと同じです。以下のデュークの回答でも同じことがわかります。
SP Sandhu 2012

回答:


250

Beejの有名なネットワークプログラミングガイドは、すばらしい説明を提供しています。

一部のドキュメントでは、神秘的な「PF_INET」についての言及があります。これは自然界ではめったに見られない奇妙なエーテルの獣ですが、ここで少しはっきりさせておきましょう。昔は、アドレスファミリ(「AF_INET」の「AF」が何を意味するか)が、プロトコルファミリ(「PF_INET」の「PF」が何を意味するか)によって参照されるいくつかのプロトコルをサポートする可能性があると考えられていました)。
それは起こりませんでした。しかたがない。したがって、正しいことは、struct sockaddr_inでAF_INETを使用し、socket()の呼び出しでPF_INETを使用することです。しかし実際には、AF_INETはどこでも使用できます。そして、それがWリチャードスティーブンスが彼の本で行うことなので、それをここで行います。


68

Linuxカーネルのソースコードで、PF_INETとAF_INETは同じであることがわかりました。次のコードは、Linuxカーネル3.2.21ツリーの204行目のinclude / linux / socket.hファイルからのものです。

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

確かにデューク、以前のカーネルでも同じですか、バージョン3.0より前のカーネルですか?
SP Sandhu

1
私が知っている限りでは、カーネルとlibcのすべてのバージョンで、PF_ * == AF_ *
Duke

これはLinux以外のプラットフォームに当てはまりますか?
善人2013

1
念のため、インクルードしたヘッダーファイルを確認する必要があると思います:)
Duke

Ubuntu / Debianで私はAFの定義を/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
Petr Javorik

48
  • AF =アドレスファミリ
  • PF =プロトコルファミリ

意味、AF_INETインターネットからのアドレス、具体的にはIPアドレスを指します。PF_INETプロトコル内のすべてのことを指し、通常はソケット/ポートです。

socket(2)およびbind(2)のマニュアルページを読むことを検討してください。sin_addrフィールドについては、次のように設定してください。

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

@codemacに感謝します、私はaddr.sin_addr.s_addr = inet_addr( "127.0.0.1");を使用しました しかし、inet_pton()は何のためのものですか?
SP Sandhu '18 / 07/18

また、manページの場合、man bind(2)またはman bind()と入力すると、予期しないトークン「(」エラーがターミナルに表示されますが、man bindはbashビルトインのバインドの説明を表示します。bind()のmanページを取得する方法bind()関数?
SP Sandhu '18 / 07/18

@ jatt.beas:構文はman <section> <topic>、たとえばman 2 bindです。
Frerich Raabe、2011

11

実際、AF_とPF_は同じものです。ウィキペディアにいくつかの単語がありますあなたの混乱を解消します

プロトコルタイプ(ファミリ)と、それぞれが使用できる特定のアドレスタイプを区別する、ソケットインターフェイスの元の設計コンセプト。プロトコルファミリには複数のアドレスタイプがあることが想定されていました。アドレスタイプは、PF_の代わりに接頭辞AF_を使用して、追加の記号定数によって定義されました。AF_-identifiersは、プロトコルファミリではなく、アドレスタイプを具体的に処理するすべてのデータ構造を対象としています。ただし、このプロトコルとアドレスタイプの分離の概念には実装のサポートがなく、AF_定数は対応するプロトコル識別子によって単純に定義されたため、AF_定数とPF_定数の違いは、実用上重大な結果をもたらさない技術的な議論になっています。実際、両方の形式の適切な使用法には多くの混乱が存在します。


4

AF_INET =アドレス形式、インターネット= IPアドレス

PF_INET =パケット形式、インターネット= IP、TCP / IPまたはUDP / IP

AF_INETは、作成するソケットに使用されるアドレスファミリです(この場合は、インターネットプロトコルアドレス)。たとえば、Linuxカーネルは、UNIXソケットやIPXなどの29の他のアドレスファミリをサポートし、IRDAおよびBluetoothとの通信もサポートします(AF_IRDAおよびAF_BLUETOOTH、ただし、このような低レベルでこれらを使用するかどうかは疑問です)。

ほとんどの場合、AF_INETを使用してネットワーク経由のソケットプログラミングを行うのが最も安全なオプションです。

つまり、AF_INETはインターネットからのアドレス、具体的にはIPアドレスを指します。

PF_INETは、プロトコル内のすべてのものを指し、通常はソケット/ポートです。


3

それが重要な状況があります。

socket()CygwinでAF_INETを渡すと、ソケットがランダムにリセットされる場合とされない場合があります。PF_INETを渡すと、接続が正しく機能します。

Cygwinは確かにソケットプログラミングにとって大きな混乱ですが、これ AF_INETとPF_INETが同一でない実際のケースです。


6
説明してください。#define PF_INET AF_INETCygwin ので見つけますsocket.h
Lorneの侯爵

3

ヘッダーファイルを確認すると問題が解決します。システムコンパイラを確認できます。

私のシステムでは、AF_INET == PF_INET

AF ==アドレスファミリおよびPF ==プロトコルファミリ

プロトコルファミリ。アドレスファミリと同じです。

ここに画像の説明を入力してください


1
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h
noobninja
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.