「すべてがファイル」がUnixの主要な概念の1つであることは理解していますが、ソケットは、通常のファイルシステムインターフェイスとは異なり、カーネルが提供するさまざまなAPI(ソケット、sendto、recvなど)を使用します。
この「すべてがファイルです」はどのように適用されますか?
ソケットは異なるAPIを使用します
それは完全に真実ではありません。ソケットで使用する追加の関数がいくつかありますが、たとえば、ソケットfdで通常のread()
とwrite()
を使用できます。
この「すべてがファイルです」はどのように適用されますか?
ファイル記述子が含まれるという意味で。
「ファイル」の定義がファイルシステムに格納されたバイトの個別のシーケンスである場合、すべてがファイルであるとは限りません。ただし、ファイルの定義がよりハンドルのようなものである場合(つまり、情報の導管、つまりI/O接続)は、「すべてがファイルである」ことが理にかなっています。これらのことは必然的にバイトのシーケンスを伴いますが、それらがどこから来るか、どこに行くかは状況によって異なります。
しかし、それは文字通り実際には意図されていません。 daemon はファイルではなく、デーモンはプロセスです。ただし、 [〜#〜] ipc [〜#〜] を実行している場合、別のプロセスに関連付ける方法は、ファイルスタイルのエンティティによって軽減される可能性があります。
「すべてがファイルである」と言っても過言ではありません。それは1970年代に小説であり、それはUNIXの主要な特徴です 。しかし、それは明らかにマーケティング・コンセプトであり、UNIXの実際の基盤ではありません。すべてをファイルとして扱うことは、有益でも賢明でもありません。
CPUはファイルですか?プログラムはCPUをread()して新しい命令を取得していますか? RAMファイルですか?プログラムは次のバイトをread()しますか?
当時、フロッピーディスク用の1つのAPIとハードディスク用の別のAPI、磁気テープ用の別のAPI、異なる端末用のさまざまなAPIなどを提供する種類のOSがありました。 IBMメインフレームシステムでは、ハードディスク上にさまざまなタイプのファイルがあり、それぞれに異なるAPIが提供されていました。したがって、UNIXの「it is a file」アプローチと「stdin/stdout/stderr」アプローチは、ユーザーとプログラマの両方に非常にエレガントな抽象化をもたらしました。
ネットワークでは、この特定の抽象化はうまくいきませんでした。また、害はなく、OSの全体的な優雅さと一貫性がわずかに低下します。しかし、それは機能します。今日、システムのどこかに/dev/myinternetz/www/google/com/tcp/80
というファイルがありますか?ニースHTMLでopen()、query()、およびread()の答えを返すことができますか?番号?これは、「ファイルである」という抽象化は、ネットワーク上でのやり取りにはあまり便利ではなかったためです。実際にはあまり効果がありません。 漏れやすい抽象化の法則 の動作.
ソケットをstat
すると、inode番号と通常のファイルのその他の特性があることがわかるので、ファイルシステム上のファイルとして分類します。例:
# file live
live: socket
# stat live
File: `live'
Size: 0 Blocks: 0 IO Block: 4096 socket
Device: fc03h/64515d Inode: 198817 Links: 1
Access: (0660/srw-rw----) Uid: (23129/ icinga) Gid: (23130/icinga-cmd)
Access: 2014-11-07 09:27:59.000000000 -0800
Modify: 2014-11-05 09:27:03.000000000 -0800
Change: 2014-11-05 09:27:03.000000000 -0800
11/17。 Linux(ext3)の追加情報:ソケットにはiノード(ディスク上の256バイトのブロック)がありますが、データブロックはありません(これを確認するには、iノードを抽出してデータブロックポインターを調べるか、またはブロックカウント0を示すdebugfs 'stat'を実行します。したがって、ファイルのメタデータ(所有者、グループ、権限など)はありますが、ディスク上のデータコンテンツはありません。これは通常の空のファイル(touch /tmp/foo
)ブロックカウントも0です。最初のケースでは、iノードの「タイプ」フィールドに「ソケット」が表示されます。 2番目のケースでは、「通常のファイル」が表示されます。
参照: ext2 iノード構造 ; stat
、dumpe2fs
およびdebugfs
コマンド。
ソケットはファイルです。ソケットでread
とwrite
を使用できます。これらは recv
と send
を呼び出すのと同じです。 とflags=0
。 close
で閉じます。ファイル記述子をシャッフルする必要がある場合は、 dup
やその他の方法で移動できます。 fcntl
を使用していくつかのフラグを設定し、 fdopen
を呼び出した後にstdioバッファリングを使用できます。リストは続きます。非常に重要なことに、ソケットを含むすべてのタイプのファイルで select
および poll
を呼び出すことができるため、これらの関数はプログラムがブロックできるようにしますファイル記述子をリストするだけで、何らかの手段で入力を受け取るまで。
一部のソケットタイプ(recv
およびsend
、 shutdown
など)には追加のシステムコールがあります。デバイス( ioctl
)。
すべてのファイルにnamesがあるわけではありません。また、そうしたファイルのうち、必ずしもディレクトリ構造に存在するとは限りません。 pipe
によって作成されたパイプ(たとえば、シェルパイプライン内)および socketpair
によって作成されたソケットには名前はありませんが、まだファイル。 socket
によって作成されたソケットには、その構文がドメインに依存する名前があります。この名前はstruct sockaddr
to bind
およびその他の関数。 Unixの場合(AF_UNIX
)ソケット、名前は struct sockaddr_un
、これはファミリーであり文字列です。文字列に応じて、これはファイル名(多くのUNIXバリアントではmknod
を使用して名前付きソケットを作成できます)またはそうではありません(抽象名前空間)。 IPv4(AF_INET
)ソケット、名前は struct sockaddr_in
、ポート番号とIPアドレス、およびprotocol
呼び出しからのsocket
が含まれます。