les sockets utilisent différentes API
Ce n'est pas tout à fait vrai. Il existe quelques fonctions supplémentaires à utiliser avec les sockets, mais vous pouvez utiliser, par exemple, normal read()
et write()
sur un socket fd.
comment ce "Tout est un fichier" s'applique-t-il ici?
En ce sens qu'un descripteur de fichier est impliqué.
Si votre définition de «fichier» est une séquence discrète d'octets stockée dans un système de fichiers, alors tout n'est pas un fichier. Cependant, si votre définition de fichier ressemble davantage à un «conduit d'information», c'est-à-dire une connexion d'E / S - alors «tout est un fichier» commence à avoir plus de sens. Ces choses impliquent inévitablement des séquences d'octets, mais d'où elles viennent ou vont peuvent différer contextuellement.
Ce n'est pas vraiment destiné à la lettre, cependant. Un démon n'est pas un fichier, un démon est un processus; mais si vous faites IPC, votre méthode de relation avec un autre processus pourrait bien être atténuée par des entités de style de fichier.
"Tout est un fichier" n'est qu'une surestimation. Il était nouveau dans les années 1970 et il a été une caractéristique distinctive primaire d'UNIX. Mais ce n'est qu'un concept marketing, pas une véritable fondation d'UNIX, car ce n'est évidemment pas vrai. Il n'est ni avantageux ni sensé de TOUT traiter comme un fichier.
Le CPU est-il un fichier? Votre programme lit-il () un CPU pour obtenir une nouvelle instruction? La RAM est-elle un fichier? Votre programme lit-il l'octet suivant?
À l'époque, il y avait des types de système d'exploitation qui vous donnaient une API pour une disquette et une API différente pour un disque dur, une API différente pour la bande magnétique et un tas d'API différentes pour différents terminaux et ainsi de suite. Les systèmes mainframe IBM avaient différents types de fichiers sur les disques durs et vous ont donné une API différente pour chacun d'eux, croyez-le ou non! L'approche UNIX "c'est un fichier", ainsi que l'approche "stdin / stdout / stderr", ont apporté une abstraction très élégante aux utilisateurs et aux programmeurs.
Avec le réseau, cette abstraction particulière n'a tout simplement pas fonctionné. Et il n'y a pas de mal, juste un peu moins d'élégance générale et de cohérence de l'OS. Mais ça marche. Voyez-vous un fichier appelé
/dev/myinternetz/www/google/com/tcp/80
n'importe où sur votre système aujourd'hui? Pouvez-vous l'ouvrir (), écrire () une requête et lire () la réponse en joli HTML? Non? En effet, cette abstraction "est un fichier" n'était pas très pratique pour interagir sur le réseau. Cela ne fonctionnerait pas trop bien dans la pratique. Loi des abstractions qui fuient en action.la source
/dev/tcp/www.google.com/80
. Ce n'est cependant pas un fichier réel - bash le simule./dev/mem
ou/dev/kmem
si vous le vouliez.Les sockets sont des fichiers. Vous pouvez utiliser
read
etwrite
sur un socket: ils sont équivalents à appelerrecv
etsend
avecflags=0
. Vous les fermez avecclose
. Vous pouvez les déplacer avecdup
et vos amis si vous avez besoin de mélanger les descripteurs de fichiers. Vous pouvez définir des indicateurs avecfcntl
et utiliser la mise en mémoire tampon stdio après l'appelfdopen
. La liste continue. Très important, vous pouvez appelerselect
etpoll
sur n'importe quel type de fichier, y compris les sockets, de sorte que ces fonctions permettent à un programme de bloquer jusqu'à ce qu'il reçoive une entrée par n'importe quel moyen simplement en listant les descripteurs de fichier.Il y a des appels système supplémentaires pour certains types de socket (
recv
etsend
,shutdown
, etc.), comme il y a un appel système supplémentaire pour les périphériques (ioctl
).Tous les fichiers n'ont pas de nom , et parmi ceux qui le font, ils ne vivent pas toujours dans la structure du répertoire. Les tuyaux créés par
pipe
( par exemple dans un pipeline shell) et les sockets créés parsocketpair
n'ont pas de nom, mais ce sont toujours des fichiers. Les sockets créées parsocket
ont un nom dont la syntaxe dépend du domaine. Ce nom est passé dans unestruct sockaddr
àbind
et d'autres fonctions. Pour uneAF_UNIX
socket Unix ( ), le nom est astruct sockaddr_un
, qui est une famille et une chaîne; selon la chaîne, il peut s'agir d'un nom de fichier (les sockets nommées peuvent être créées avecmknod
de nombreuses variantes unix) ou non (l'espace de noms abstrait). Pour uneAF_INET
socket IPv4 ( ), le nom est unstruct sockaddr_in
, contenant un numéro de port et une adresse IP, plus leprotocol
de l'socket
appel.la source
Si vous êtes
stat
un socket, vous verrez qu'il a un numéro d'inode et d'autres caractéristiques des fichiers normaux, donc je le classerais comme un fichier sur le système de fichiers. Exemple:11/17. Informations supplémentaires pour Linux (ext3): Un socket a un inode (qui est un bloc de 256 octets sur le disque) mais n'a pas de blocs de données (vous pouvez le vérifier en extrayant l'inode et en examinant les pointeurs de bloc de données; ou en exécutant debugfs 'stat' qui affiche un Blockcount de 0). Ainsi, il contient des métadonnées de fichier (propriétaire, groupe, autorisations, etc.) mais aucun contenu de données sur le disque. Ceci est identique à un fichier vide normal (
touch /tmp/foo
) qui a également un nombre de blocs de 0. Dans le premier cas, le champ "type" dans l'inode affiche "socket"; dans le deuxième cas, il affiche "fichier normal".Références: structure inode ext2 ;
stat
,dumpe2fs
Et lesdebugfs
commandes.la source
file
ou à utiliserstat
en fait un fichier.